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_SIGNAL_PORTS_H
00028 #define SC_SIGNAL_PORTS_H
00029
00030
00031 #include "sysc/communication/sc_event_finder.h"
00032 #include "sysc/communication/sc_port.h"
00033 #include "sysc/communication/sc_signal_ifs.h"
00034 #include "sysc/datatypes/bit/sc_logic.h"
00035 #include "sysc/tracing/sc_trace.h"
00036
00037
00038 #include "sysc/communication/sc_prim_channel.h"
00039
00040 #if ! defined( SC_DISABLE_VIRTUAL_BIND )
00041 # define SC_VIRTUAL_ virtual
00042 #else
00043 # define SC_VIRTUAL_
00044 #endif
00045
00046 namespace sc_core {
00047
00048
00057 extern void sc_deprecated_add_trace();
00058
00059 struct sc_trace_params
00060 {
00061 sc_trace_file* tf;
00062 std::string name;
00063
00064 sc_trace_params( sc_trace_file* tf_, const std::string& name_ )
00065 : tf( tf_ ), name( name_ )
00066 {}
00067 };
00068
00069
00070 typedef std::vector<sc_trace_params*> sc_trace_params_vec;
00071
00072
00073
00079 template <class T>
00080 class sc_in
00081 : public sc_port<sc_signal_in_if<T>,1,SC_ONE_OR_MORE_BOUND>
00082 {
00083 public:
00084
00085
00086
00087 typedef T data_type;
00088
00089 typedef sc_signal_in_if<data_type> if_type;
00090 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
00091 typedef sc_in<data_type> this_type;
00092 typedef typename base_type::port_type base_port_type;
00093
00094 typedef if_type in_if_type;
00095 typedef base_type in_port_type;
00096 typedef sc_signal_inout_if<data_type> inout_if_type;
00097 typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
00098
00099 public:
00100
00101
00102
00103 sc_in()
00104 : base_type(), m_traces( 0 ),
00105 m_change_finder_p(0)
00106 { CHNL_MTX_INIT_( m_mutex ); }
00107
00108 explicit sc_in( const char* name_ )
00109 : base_type( name_ ), m_traces( 0 ),
00110 m_change_finder_p(0)
00111 { CHNL_MTX_INIT_( m_mutex ); }
00112
00113 explicit sc_in( const in_if_type& interface_ )
00114 : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00115 m_change_finder_p(0)
00116 { CHNL_MTX_INIT_( m_mutex ); }
00117
00118 sc_in( const char* name_, const in_if_type& interface_ )
00119 : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00120 m_change_finder_p(0)
00121 { CHNL_MTX_INIT_( m_mutex ); }
00122
00123 explicit sc_in( in_port_type& parent_ )
00124 : base_type( parent_ ), m_traces( 0 ),
00125 m_change_finder_p(0)
00126 { CHNL_MTX_INIT_( m_mutex ); }
00127
00128 sc_in( const char* name_, in_port_type& parent_ )
00129 : base_type( name_, parent_ ), m_traces( 0 ),
00130 m_change_finder_p(0)
00131 { CHNL_MTX_INIT_( m_mutex ); }
00132
00133 explicit sc_in( inout_port_type& parent_ )
00134 : base_type(), m_traces( 0 ),
00135 m_change_finder_p(0)
00136 { CHNL_MTX_INIT_( m_mutex );
00137 sc_port_base::bind( parent_ ); }
00138
00139 sc_in( const char* name_, inout_port_type& parent_ )
00140 : base_type( name_ ), m_traces( 0 ),
00141 m_change_finder_p(0)
00142 { CHNL_MTX_INIT_( m_mutex );
00143 sc_port_base::bind( parent_ ); }
00144
00145 sc_in( this_type& parent_ )
00146 : base_type( parent_ ), m_traces( 0 ),
00147 m_change_finder_p(0)
00148 { CHNL_MTX_INIT_( m_mutex ); }
00149
00150 sc_in( const char* name_, this_type& parent_ )
00151 : base_type( name_, parent_ ), m_traces( 0 ),
00152 m_change_finder_p(0)
00153 { CHNL_MTX_INIT_( m_mutex ); }
00154
00155
00156
00157
00158 virtual ~sc_in()
00159 {
00160 CHNL_MTX_DESTROY_( m_mutex );
00161 remove_traces();
00162 delete m_change_finder_p;
00163 }
00164
00165
00166
00167
00168 SC_VIRTUAL_ void bind( const in_if_type& interface_ )
00169 { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00170
00171 SC_VIRTUAL_ void bind( in_if_type& interface_ )
00172 { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
00173
00174 void operator () ( const in_if_type& interface_ )
00175 { this->bind( interface_ ); }
00176
00177
00178
00179
00180 SC_VIRTUAL_ void bind( in_port_type& parent_ )
00181 { sc_port_base::bind( parent_ ); }
00182
00183 void operator () ( in_port_type& parent_ )
00184 { this->bind( parent_ ); }
00185
00186
00187
00188
00189 SC_VIRTUAL_ void bind( inout_port_type& parent_ )
00190 { sc_port_base::bind( parent_ ); }
00191
00192 void operator () ( inout_port_type& parent_ )
00193 { this->bind( parent_ ); }
00194
00195
00196
00197
00198
00199
00200 const sc_event& default_event() const
00201 { return (*this)->default_event(); }
00202
00203
00204
00205
00206 const sc_event& value_changed_event() const
00207 { return (*this)->value_changed_event(); }
00208
00209
00210
00211
00212 const data_type& read() const
00213 { return (*this)->read(); }
00214
00215 operator const data_type& () const
00216 { return (*this)->read(); }
00217
00218
00219
00220
00221 bool event() const
00222 { return (*this)->event(); }
00223
00224
00225
00226
00227 sc_event_finder& value_changed() const
00228 {
00229
00230 chnl_scoped_lock lock( m_mutex );
00231
00232 if ( !m_change_finder_p )
00233 {
00234 m_change_finder_p = new sc_event_finder_t<in_if_type>(
00235 *this, &in_if_type::value_changed_event );
00236 }
00237 return *m_change_finder_p;
00238
00239 }
00240
00241
00242
00243
00244
00245
00246 virtual void end_of_elaboration();
00247
00248 virtual const char* kind() const
00249 { return "sc_in"; }
00250
00251
00252 void add_trace( sc_trace_file*, const std::string& ) const;
00253
00254
00255 void add_trace_internal( sc_trace_file*, const std::string& ) const;
00256
00257 protected:
00258
00259 void remove_traces() const;
00260
00261 mutable sc_trace_params_vec* m_traces;
00262
00263 protected:
00264
00265
00266 virtual int vbind( sc_interface& );
00267 virtual int vbind( sc_port_base& );
00268
00269
00270
00271
00272
00273
00274 SC_VIRTUAL_ void bind( base_port_type& parent_ )
00275 { sc_port_base::bind( parent_ ); }
00276
00277
00278 private:
00279 mutable sc_event_finder* m_change_finder_p;
00280
00284
00285 mutable CHNL_MTX_TYPE_ m_mutex;
00286
00287 private:
00288
00289
00290 sc_in( const this_type& );
00291 this_type& operator = ( const this_type& );
00292
00293 #ifdef __GNUC__
00294
00295
00296
00297
00298 static data_type dummy;
00299 #endif
00300 };
00301
00302 template<typename T>
00303 ::std::ostream& operator << ( ::std::ostream& os, const sc_in<T>& a )
00304 {
00305 return os << a->read();
00306 }
00307
00308
00309
00310
00311
00312
00313 template <class T>
00314 inline
00315 void
00316 sc_in<T>::end_of_elaboration()
00317 {
00318 if( m_traces != 0 ) {
00319 for( int i = 0; i < (int)m_traces->size(); ++ i ) {
00320 sc_trace_params* p = (*m_traces)[i];
00321 in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
00322 sc_trace( p->tf, iface->read(), p->name );
00323 }
00324 remove_traces();
00325 }
00326 }
00327
00328
00329
00330
00331 template <class T>
00332 inline
00333 void
00334 sc_in<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_ )
00335 const
00336 {
00337 if( tf_ != 0 ) {
00338 if( m_traces == 0 ) {
00339 m_traces = new sc_trace_params_vec;
00340 }
00341 m_traces->push_back( new sc_trace_params( tf_, name_ ) );
00342 }
00343 }
00344
00345 template <class T>
00346 inline
00347 void
00348 sc_in<T>::add_trace( sc_trace_file* tf_, const std::string& name_ )
00349 const
00350 {
00351 sc_deprecated_add_trace();
00352 add_trace_internal(tf_, name_);
00353 }
00354
00355 template <class T>
00356 inline
00357 void
00358 sc_in<T>::remove_traces() const
00359 {
00360 if( m_traces != 0 ) {
00361 for( int i = (int)m_traces->size() - 1; i >= 0; -- i ) {
00362 delete (*m_traces)[i];
00363 }
00364 delete m_traces;
00365 m_traces = 0;
00366 }
00367 }
00368
00369
00370
00371
00372 template <class T>
00373 inline
00374 int
00375 sc_in<T>::vbind( sc_interface& interface_ )
00376 {
00377 return sc_port_b<if_type>::vbind( interface_ );
00378 }
00379
00380 template <class T>
00381 inline
00382 int
00383 sc_in<T>::vbind( sc_port_base& parent_ )
00384 {
00385 in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
00386 if( in_parent != 0 ) {
00387 sc_port_base::bind( *in_parent );
00388 return 0;
00389 }
00390 inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
00391 if( inout_parent != 0 ) {
00392 sc_port_base::bind( *inout_parent );
00393 return 0;
00394 }
00395
00396 return 2;
00397 }
00398
00399
00400
00406 template <>
00407 class sc_in<bool> :
00408 public sc_port<sc_signal_in_if<bool>,1,SC_ONE_OR_MORE_BOUND>
00409 {
00410 public:
00411
00412
00413
00414 typedef bool data_type;
00415
00416 typedef sc_signal_in_if<data_type> if_type;
00417 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
00418 typedef sc_in<data_type> this_type;
00419 typedef base_type::port_type base_port_type;
00420
00421 typedef if_type in_if_type;
00422 typedef base_type in_port_type;
00423 typedef sc_signal_inout_if<data_type> inout_if_type;
00424 typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
00425
00426 public:
00427
00428
00429
00430 sc_in()
00431 : base_type(), m_traces( 0 ), m_change_finder_p(0),
00432 m_neg_finder_p(0), m_pos_finder_p(0)
00433 { CHNL_MTX_INIT_( m_mutex ); }
00434
00435 explicit sc_in( const char* name_ )
00436 : base_type( name_ ), m_traces( 0 ), m_change_finder_p(0),
00437 m_neg_finder_p(0), m_pos_finder_p(0)
00438 { CHNL_MTX_INIT_( m_mutex ); }
00439
00440 explicit sc_in( const in_if_type& interface_ )
00441 : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00442 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00443 { CHNL_MTX_INIT_( m_mutex ); }
00444
00445 sc_in( const char* name_, const in_if_type& interface_ )
00446 : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00447 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00448 { CHNL_MTX_INIT_( m_mutex ); }
00449
00450 explicit sc_in( in_port_type& parent_ )
00451 : base_type( parent_ ), m_traces( 0 ),
00452 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00453 { CHNL_MTX_INIT_( m_mutex ); }
00454
00455 sc_in( const char* name_, in_port_type& parent_ )
00456 : base_type( name_, parent_ ), m_traces( 0 ),
00457 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00458 { CHNL_MTX_INIT_( m_mutex ); }
00459
00460 explicit sc_in( inout_port_type& parent_ )
00461 : base_type(), m_traces( 0 ),
00462 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00463 { CHNL_MTX_INIT_( m_mutex );
00464 sc_port_base::bind( parent_ ); }
00465
00466 sc_in( const char* name_, inout_port_type& parent_ )
00467 : base_type( name_ ), m_traces( 0 ),
00468 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00469 { CHNL_MTX_INIT_( m_mutex );
00470 sc_port_base::bind( parent_ ); }
00471
00472 sc_in( this_type& parent_ )
00473 : base_type( parent_ ), m_traces( 0 ),
00474 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00475 { CHNL_MTX_INIT_( m_mutex ); }
00476
00477 #if defined(TESTING)
00478 sc_in( const this_type& parent_ )
00479 : base_type( *(in_if_type*)parent_.get_interface() ) , m_traces( 0 ),
00480 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00481 { CHNL_MTX_INIT_( m_mutex ); }
00482 #endif
00483
00484 sc_in( const char* name_, this_type& parent_ )
00485 : base_type( name_, parent_ ), m_traces( 0 ),
00486 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00487 { CHNL_MTX_INIT_( m_mutex ); }
00488
00489
00490
00491
00492 virtual ~sc_in()
00493 {
00494 remove_traces();
00495 CHNL_MTX_DESTROY_( m_mutex );
00496 delete m_change_finder_p;
00497 delete m_neg_finder_p;
00498 delete m_pos_finder_p;
00499 }
00500
00501
00502
00503
00504 SC_VIRTUAL_ void bind( const in_if_type& interface_ )
00505 { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00506
00507 SC_VIRTUAL_ void bind( in_if_type& interface_ )
00508 { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
00509
00510 void operator () ( const in_if_type& interface_ )
00511 { this->bind( interface_ ); }
00512
00513
00514
00515
00516 SC_VIRTUAL_ void bind( in_port_type& parent_ )
00517 { sc_port_base::bind( parent_ ); }
00518
00519 void operator () ( in_port_type& parent_ )
00520 { this->bind( parent_ ); }
00521
00522
00523
00524
00525 SC_VIRTUAL_ void bind( inout_port_type& parent_ )
00526 { sc_port_base::bind( parent_ ); }
00527
00528 void operator () ( inout_port_type& parent_ )
00529 { this->bind( parent_ ); }
00530
00531
00532
00533
00534
00535
00536 const sc_event& default_event() const
00537 { return (*this)->default_event(); }
00538
00539
00540
00541
00542 const sc_event& value_changed_event() const
00543 { return (*this)->value_changed_event(); }
00544
00545
00546
00547 const sc_event& posedge_event() const
00548 { return (*this)->posedge_event(); }
00549
00550
00551
00552 const sc_event& negedge_event() const
00553 { return (*this)->negedge_event(); }
00554
00555
00556
00557
00558 const data_type& read() const
00559 { return (*this)->read(); }
00560
00561 operator const data_type& () const
00562 { return (*this)->read(); }
00563
00564
00565
00566
00567 sc_event_finder& pos() const
00568 {
00569
00570 chnl_scoped_lock lock( m_mutex );
00571
00572 if ( !m_pos_finder_p )
00573 {
00574 m_pos_finder_p = new sc_event_finder_t<in_if_type>(
00575 *this, &in_if_type::posedge_event );
00576 }
00577 return *m_pos_finder_p;
00578
00579 }
00580
00581
00582
00583 sc_event_finder& neg() const
00584 {
00585
00586 chnl_scoped_lock lock( m_mutex );
00587
00588 if ( !m_neg_finder_p )
00589 {
00590 m_neg_finder_p = new sc_event_finder_t<in_if_type>(
00591 *this, &in_if_type::negedge_event );
00592 }
00593 return *m_neg_finder_p;
00594
00595 }
00596
00597
00598
00599
00600 bool event() const
00601 { return (*this)->event(); }
00602
00603
00604
00605 bool posedge() const
00606 { return (*this)->posedge(); }
00607
00608
00609
00610 bool negedge() const
00611 { return (*this)->negedge(); }
00612
00613
00614
00615 sc_event_finder& value_changed() const
00616 {
00617
00618 chnl_scoped_lock lock( m_mutex );
00619
00620 if ( !m_change_finder_p )
00621 {
00622 m_change_finder_p = new sc_event_finder_t<in_if_type>(
00623 *this, &in_if_type::value_changed_event );
00624 }
00625 return *m_change_finder_p;
00626
00627 }
00628
00629
00630
00631
00632
00633
00634 virtual void end_of_elaboration();
00635
00636 virtual const char* kind() const
00637 { return "sc_in"; }
00638
00639
00640 void add_trace( sc_trace_file*, const std::string& ) const;
00641
00642
00643 void add_trace_internal( sc_trace_file*, const std::string& ) const;
00644
00645 protected:
00646
00647 void remove_traces() const;
00648
00649 mutable sc_trace_params_vec* m_traces;
00650
00651 protected:
00652
00653
00654 virtual int vbind( sc_interface& );
00655 virtual int vbind( sc_port_base& );
00656
00657
00658
00659
00660
00661
00662 SC_VIRTUAL_ void bind( base_port_type& parent_ )
00663 { sc_port_base::bind( parent_ ); }
00664
00665 private:
00666 mutable sc_event_finder* m_change_finder_p;
00667 mutable sc_event_finder* m_neg_finder_p;
00668 mutable sc_event_finder* m_pos_finder_p;
00669
00673
00674 mutable CHNL_MTX_TYPE_ m_mutex;
00675
00676 private:
00677
00678
00679 #if defined(TESTING)
00680 #else
00681 sc_in( const this_type& );
00682 #endif
00683 this_type& operator = ( const this_type& );
00684
00685 #ifdef __GNUC__
00686
00687
00688
00689
00690 static data_type dummy;
00691 #endif
00692 };
00693
00694
00695
00701 template <>
00702 class sc_in<sc_dt::sc_logic>
00703 : public sc_port<sc_signal_in_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
00704 {
00705 public:
00706
00707
00708
00709 typedef sc_dt::sc_logic data_type;
00710
00711 typedef sc_signal_in_if<data_type> if_type;
00712 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
00713 typedef sc_in<data_type> this_type;
00714 typedef base_type::port_type base_port_type;
00715
00716 typedef if_type in_if_type;
00717 typedef base_type in_port_type;
00718 typedef sc_signal_inout_if<data_type> inout_if_type;
00719 typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
00720
00721 public:
00722
00723
00724
00725 sc_in()
00726 : base_type(), m_traces( 0 ),
00727 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00728 { CHNL_MTX_INIT_( m_mutex ); }
00729
00730 explicit sc_in( const char* name_ )
00731 : base_type( name_ ), m_traces( 0 ),
00732 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00733 { CHNL_MTX_INIT_( m_mutex ); }
00734
00735 explicit sc_in( const in_if_type& interface_ )
00736 : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00737 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00738 { CHNL_MTX_INIT_( m_mutex ); }
00739
00740 sc_in( const char* name_, const in_if_type& interface_ )
00741 : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00742 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00743 { CHNL_MTX_INIT_( m_mutex ); }
00744
00745 explicit sc_in( in_port_type& parent_ )
00746 : base_type( parent_ ), m_traces( 0 ),
00747 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00748 { CHNL_MTX_INIT_( m_mutex ); }
00749
00750 sc_in( const char* name_, in_port_type& parent_ )
00751 : base_type( name_, parent_ ), m_traces( 0 ),
00752 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00753 { CHNL_MTX_INIT_( m_mutex ); }
00754
00755 explicit sc_in( inout_port_type& parent_ )
00756 : base_type(), m_traces( 0 ),
00757 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00758 { CHNL_MTX_INIT_( m_mutex );
00759 sc_port_base::bind( parent_ ); }
00760
00761 sc_in( const char* name_, inout_port_type& parent_ )
00762 : base_type( name_ ), m_traces( 0 ),
00763 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00764 { CHNL_MTX_INIT_( m_mutex );
00765 sc_port_base::bind( parent_ ); }
00766
00767 sc_in( this_type& parent_ )
00768 : base_type( parent_ ), m_traces( 0 ),
00769 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00770 { CHNL_MTX_INIT_( m_mutex ); }
00771
00772 sc_in( const char* name_, this_type& parent_ )
00773 : base_type( name_, parent_ ), m_traces( 0 ),
00774 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00775 { CHNL_MTX_INIT_( m_mutex ); }
00776
00777
00778
00779
00780 virtual ~sc_in()
00781 {
00782 remove_traces();
00783 CHNL_MTX_DESTROY_( m_mutex );
00784 delete m_change_finder_p;
00785 delete m_neg_finder_p;
00786 delete m_pos_finder_p;
00787 }
00788
00789
00790
00791
00792 SC_VIRTUAL_ void bind( const in_if_type& interface_ )
00793 { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00794
00795 SC_VIRTUAL_ void bind( in_if_type& interface_ )
00796 { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
00797
00798 void operator () ( const in_if_type& interface_ )
00799 { this->bind( interface_ ); }
00800
00801
00802
00803
00804 SC_VIRTUAL_ void bind( in_port_type& parent_ )
00805 { sc_port_base::bind( parent_ ); }
00806
00807 void operator () ( in_port_type& parent_ )
00808 { this->bind( parent_ ); }
00809
00810
00811
00812
00813 SC_VIRTUAL_ void bind( inout_port_type& parent_ )
00814 { sc_port_base::bind( parent_ ); }
00815
00816 void operator () ( inout_port_type& parent_ )
00817 { this->bind( parent_ ); }
00818
00819
00820
00821
00822
00823
00824 const sc_event& default_event() const
00825 { return (*this)->default_event(); }
00826
00827
00828
00829
00830 const sc_event& value_changed_event() const
00831 { return (*this)->value_changed_event(); }
00832
00833
00834
00835 const sc_event& posedge_event() const
00836 { return (*this)->posedge_event(); }
00837
00838
00839
00840 const sc_event& negedge_event() const
00841 { return (*this)->negedge_event(); }
00842
00843
00844
00845
00846 const data_type& read() const
00847 { return (*this)->read(); }
00848
00849 operator const data_type& () const
00850 { return (*this)->read(); }
00851
00852
00853
00854
00855 sc_event_finder& pos() const
00856 {
00857
00858 chnl_scoped_lock lock( m_mutex );
00859
00860 if ( !m_pos_finder_p )
00861 {
00862 m_pos_finder_p = new sc_event_finder_t<in_if_type>(
00863 *this, &in_if_type::posedge_event );
00864 }
00865 return *m_pos_finder_p;
00866
00867 }
00868
00869
00870
00871 sc_event_finder& neg() const
00872 {
00873
00874 chnl_scoped_lock lock( m_mutex );
00875
00876 if ( !m_neg_finder_p )
00877 {
00878 m_neg_finder_p = new sc_event_finder_t<in_if_type>(
00879 *this, &in_if_type::negedge_event );
00880 }
00881 return *m_neg_finder_p;
00882
00883 }
00884
00885
00886
00887
00888 bool event() const
00889 { return (*this)->event(); }
00890
00891
00892
00893 bool posedge() const
00894 { return (*this)->posedge(); }
00895
00896
00897
00898 bool negedge() const
00899 { return (*this)->negedge(); }
00900
00901
00902
00903 sc_event_finder& value_changed() const
00904 {
00905
00906 chnl_scoped_lock lock( m_mutex );
00907
00908 if ( !m_change_finder_p )
00909 {
00910 m_change_finder_p = new sc_event_finder_t<in_if_type>(
00911 *this, &in_if_type::value_changed_event );
00912 }
00913 return *m_change_finder_p;
00914
00915 }
00916
00917
00918
00919
00920
00921
00922 virtual void end_of_elaboration();
00923
00924 virtual const char* kind() const
00925 { return "sc_in"; }
00926
00927
00928 void add_trace( sc_trace_file*, const std::string& ) const;
00929
00930
00931 void add_trace_internal( sc_trace_file*, const std::string& ) const;
00932
00933 protected:
00934
00935 void remove_traces() const;
00936
00937 mutable sc_trace_params_vec* m_traces;
00938
00939 protected:
00940
00941
00942 virtual int vbind( sc_interface& );
00943 virtual int vbind( sc_port_base& );
00944
00945
00946
00947
00948
00949
00950 SC_VIRTUAL_ void bind( base_port_type& parent_ )
00951 { sc_port_base::bind( parent_ ); }
00952
00953 private:
00954 mutable sc_event_finder* m_change_finder_p;
00955 mutable sc_event_finder* m_neg_finder_p;
00956 mutable sc_event_finder* m_pos_finder_p;
00957
00961
00962 mutable CHNL_MTX_TYPE_ m_mutex;
00963
00964 private:
00965
00966
00967 sc_in( const this_type& );
00968 this_type& operator = ( const this_type& );
00969
00970 #ifdef __GNUC__
00971
00972
00973
00974
00975 static data_type dummy;
00976 #endif
00977 };
00978
00979
00980
00986 template <class T>
00987 class sc_inout
00988 : public sc_port<sc_signal_inout_if<T>,1,SC_ONE_OR_MORE_BOUND>
00989 {
00990 public:
00991
00992
00993
00994 typedef T data_type;
00995
00996 typedef sc_signal_inout_if<data_type> if_type;
00997 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
00998 typedef sc_inout<data_type> this_type;
00999
01000 typedef sc_signal_in_if<data_type> in_if_type;
01001 typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
01002 typedef if_type inout_if_type;
01003 typedef base_type inout_port_type;
01004
01005 public:
01006
01007
01008
01009 sc_inout()
01010 : base_type(), m_init_val( 0 ), m_traces( 0 ),
01011 m_change_finder_p(0)
01012 { CHNL_MTX_INIT_( m_mutex ); }
01013
01014 explicit sc_inout( const char* name_ )
01015 : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
01016 m_change_finder_p(0)
01017 { CHNL_MTX_INIT_( m_mutex ); }
01018
01019 explicit sc_inout( inout_if_type& interface_ )
01020 : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
01021 m_change_finder_p(0)
01022 { CHNL_MTX_INIT_( m_mutex ); }
01023
01024 sc_inout( const char* name_, inout_if_type& interface_ )
01025 : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
01026 m_change_finder_p(0)
01027 { CHNL_MTX_INIT_( m_mutex ); }
01028
01029 explicit sc_inout( inout_port_type& parent_ )
01030 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01031 m_change_finder_p(0)
01032 { CHNL_MTX_INIT_( m_mutex ); }
01033
01034 sc_inout( const char* name_, inout_port_type& parent_ )
01035 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01036 m_change_finder_p(0)
01037 { CHNL_MTX_INIT_( m_mutex ); }
01038
01039 sc_inout( this_type& parent_ )
01040 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01041 m_change_finder_p(0)
01042 { CHNL_MTX_INIT_( m_mutex ); }
01043
01044 sc_inout( const char* name_, this_type& parent_ )
01045 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01046 m_change_finder_p(0)
01047 { CHNL_MTX_INIT_( m_mutex ); }
01048
01049
01050
01051
01052 virtual ~sc_inout();
01053
01054
01055
01056
01057
01058
01059 const sc_event& default_event() const
01060 { return (*this)->default_event(); }
01061
01062
01063
01064
01065 const sc_event& value_changed_event() const
01066 { return (*this)->value_changed_event(); }
01067
01068
01069
01070
01071 const data_type& read() const
01072 { return (*this)->read(); }
01073
01074 operator const data_type& () const
01075 { return (*this)->read(); }
01076
01077
01078
01079
01080 bool event() const
01081 { return (*this)->event(); }
01082
01083
01084
01085
01086 void write( const data_type& value_ )
01087 { (*this)->write( value_ ); }
01088
01089 this_type& operator = ( const data_type& value_ )
01090 { (*this)->write( value_ ); return *this; }
01091
01092 this_type& operator = ( const in_if_type& interface_ )
01093 { (*this)->write( interface_.read() ); return *this; }
01094
01095 this_type& operator = ( const in_port_type& port_ )
01096 { (*this)->write( port_->read() ); return *this; }
01097
01098 this_type& operator = ( const inout_port_type& port_ )
01099 { (*this)->write( port_->read() ); return *this; }
01100
01101 this_type& operator = ( const this_type& port_ )
01102 { (*this)->write( port_->read() ); return *this; }
01103
01104
01105
01106
01107 void initialize( const data_type& value_ );
01108
01109 void initialize( const in_if_type& interface_ )
01110 { initialize( interface_.read() ); }
01111
01112
01113
01114
01115
01116
01117 virtual void end_of_elaboration();
01118
01119
01120
01121
01122 sc_event_finder& value_changed() const
01123 {
01124
01125 chnl_scoped_lock lock( m_mutex );
01126
01127 if ( !m_change_finder_p )
01128 {
01129 m_change_finder_p = new sc_event_finder_t<in_if_type>(
01130 *this, &in_if_type::value_changed_event );
01131 }
01132 return *m_change_finder_p;
01133
01134 }
01135
01136 virtual const char* kind() const
01137 { return "sc_inout"; }
01138
01139 protected:
01140
01141 data_type* m_init_val;
01142
01143 public:
01144
01145
01146 void add_trace_internal( sc_trace_file*, const std::string& ) const;
01147
01148 void add_trace( sc_trace_file*, const std::string& ) const;
01149
01150 protected:
01151
01152 void remove_traces() const;
01153
01154 mutable sc_trace_params_vec* m_traces;
01155
01156 private:
01157 mutable sc_event_finder* m_change_finder_p;
01158
01162
01163 mutable CHNL_MTX_TYPE_ m_mutex;
01164
01165 private:
01166
01167
01168 sc_inout( const this_type& );
01169
01170 #ifdef __GNUC__
01171
01172
01173
01174
01175 static data_type dummy;
01176 #endif
01177 };
01178
01179 template<typename T>
01180 ::std::ostream& operator << ( ::std::ostream& os, const sc_inout<T>& a )
01181 {
01182 return os << a->read();
01183 }
01184
01185
01186
01187
01188
01189
01190 template <class T>
01191 inline
01192 sc_inout<T>::~sc_inout()
01193 {
01194 CHNL_MTX_DESTROY_( m_mutex );
01195 delete m_change_finder_p;
01196 delete m_init_val;
01197 remove_traces();
01198 }
01199
01200
01201
01202
01203 template <class T>
01204 inline
01205 void
01206 sc_inout<T>::initialize( const data_type& value_ )
01207 {
01208 inout_if_type* iface = DCAST<inout_if_type*>( this->get_interface() );
01209 if( iface != 0 ) {
01210 iface->write( value_ );
01211 } else {
01212 if( m_init_val == 0 ) {
01213 m_init_val = new data_type;
01214 }
01215 *m_init_val = value_;
01216 }
01217 }
01218
01219
01220
01221
01222 template <class T>
01223 inline
01224 void
01225 sc_inout<T>::end_of_elaboration()
01226 {
01227 if( m_init_val != 0 ) {
01228 write( *m_init_val );
01229 delete m_init_val;
01230 m_init_val = 0;
01231 }
01232 if( m_traces != 0 ) {
01233 for( int i = 0; i < (int)m_traces->size(); ++ i ) {
01234 sc_trace_params* p = (*m_traces)[i];
01235 in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
01236 sc_trace( p->tf, iface->read(), p->name );
01237 }
01238 remove_traces();
01239 }
01240 }
01241
01242
01243
01244
01245 template <class T>
01246 inline
01247 void
01248 sc_inout<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_)
01249 const
01250 {
01251 if( tf_ != 0 ) {
01252 if( m_traces == 0 ) {
01253 m_traces = new sc_trace_params_vec;
01254 }
01255 m_traces->push_back( new sc_trace_params( tf_, name_ ) );
01256 }
01257 }
01258
01259 template <class T>
01260 inline
01261 void
01262 sc_inout<T>::add_trace( sc_trace_file* tf_, const std::string& name_) const
01263 {
01264 sc_deprecated_add_trace();
01265 add_trace_internal(tf_, name_);
01266 }
01267
01268 template <class T>
01269 inline
01270 void
01271 sc_inout<T>::remove_traces() const
01272 {
01273 if( m_traces != 0 ) {
01274 for( int i = m_traces->size() - 1; i >= 0; -- i ) {
01275 delete (*m_traces)[i];
01276 }
01277 delete m_traces;
01278 m_traces = 0;
01279 }
01280 }
01281
01282
01283
01289 template <>
01290 class sc_inout<bool> :
01291 public sc_port<sc_signal_inout_if<bool>,1,SC_ONE_OR_MORE_BOUND>
01292 {
01293 public:
01294
01295
01296
01297 typedef bool data_type;
01298
01299 typedef sc_signal_inout_if<data_type> if_type;
01300 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
01301 typedef sc_inout<data_type> this_type;
01302
01303 typedef sc_signal_in_if<data_type> in_if_type;
01304 typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
01305 typedef if_type inout_if_type;
01306 typedef base_type inout_port_type;
01307
01308 public:
01309
01310
01311
01312 sc_inout()
01313 : base_type(), m_init_val( 0 ), m_traces( 0 ),
01314 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01315 { CHNL_MTX_INIT_( m_mutex ); }
01316
01317 explicit sc_inout( const char* name_ )
01318 : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
01319 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01320 { CHNL_MTX_INIT_( m_mutex ); }
01321
01322 explicit sc_inout( inout_if_type& interface_ )
01323 : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
01324 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01325 { CHNL_MTX_INIT_( m_mutex ); }
01326
01327 sc_inout( const char* name_, inout_if_type& interface_ )
01328 : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
01329 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01330 { CHNL_MTX_INIT_( m_mutex ); }
01331
01332 explicit sc_inout( inout_port_type& parent_ )
01333 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01334 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01335 { CHNL_MTX_INIT_( m_mutex ); }
01336
01337 sc_inout( const char* name_, inout_port_type& parent_ )
01338 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01339 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01340 { CHNL_MTX_INIT_( m_mutex ); }
01341
01342 sc_inout( this_type& parent_ )
01343 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01344 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01345 { CHNL_MTX_INIT_( m_mutex ); }
01346
01347 sc_inout( const char* name_, this_type& parent_ )
01348 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01349 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01350 { CHNL_MTX_INIT_( m_mutex ); }
01351
01352
01353
01354
01355 virtual ~sc_inout();
01356
01357
01358
01359
01360
01361
01362 const sc_event& default_event() const
01363 { return (*this)->default_event(); }
01364
01365
01366
01367
01368 const sc_event& value_changed_event() const
01369 { return (*this)->value_changed_event(); }
01370
01371
01372
01373 const sc_event& posedge_event() const
01374 { return (*this)->posedge_event(); }
01375
01376
01377
01378 const sc_event& negedge_event() const
01379 { return (*this)->negedge_event(); }
01380
01381
01382
01383
01384 const data_type& read() const
01385 { return (*this)->read(); }
01386
01387 operator const data_type& () const
01388 { return (*this)->read(); }
01389
01390
01391
01392
01393 sc_event_finder& pos() const
01394 {
01395
01396 chnl_scoped_lock lock( m_mutex );
01397
01398 if ( !m_pos_finder_p )
01399 {
01400 m_pos_finder_p = new sc_event_finder_t<in_if_type>(
01401 *this, &in_if_type::posedge_event );
01402 }
01403 return *m_pos_finder_p;
01404
01405 }
01406
01407
01408
01409 sc_event_finder& neg() const
01410 {
01411
01412 chnl_scoped_lock lock( m_mutex );
01413
01414 if ( !m_neg_finder_p )
01415 {
01416 m_neg_finder_p = new sc_event_finder_t<in_if_type>(
01417 *this, &in_if_type::negedge_event );
01418 }
01419 return *m_neg_finder_p;
01420
01421 }
01422
01423
01424
01425
01426 bool event() const
01427 { return (*this)->event(); }
01428
01429
01430
01431 bool posedge() const
01432 { return (*this)->posedge(); }
01433
01434
01435
01436 bool negedge() const
01437 { return (*this)->negedge(); }
01438
01439
01440
01441 void write( const data_type& value_ )
01442 { (*this)->write( value_ ); }
01443
01444 this_type& operator = ( const data_type& value_ )
01445 { (*this)->write( value_ ); return *this; }
01446
01447 this_type& operator = ( const in_if_type& interface_ )
01448 { (*this)->write( interface_.read() ); return *this; }
01449
01450 this_type& operator = ( const in_port_type& port_ )
01451 { (*this)->write( port_->read() ); return *this; }
01452
01453 this_type& operator = ( const inout_port_type& port_ )
01454 { (*this)->write( port_->read() ); return *this; }
01455
01456 this_type& operator = ( const this_type& port_ )
01457 { (*this)->write( port_->read() ); return *this; }
01458
01459
01460
01461
01462 void initialize( const data_type& value_ );
01463
01464 void initialize( const in_if_type& interface_ )
01465 { initialize( interface_.read() ); }
01466
01467
01468
01469
01470
01471
01472 virtual void end_of_elaboration();
01473
01474
01475
01476
01477 sc_event_finder& value_changed() const
01478 {
01479
01480 chnl_scoped_lock lock( m_mutex );
01481
01482 if ( !m_change_finder_p )
01483 {
01484 m_change_finder_p = new sc_event_finder_t<in_if_type>(
01485 *this, &in_if_type::value_changed_event );
01486 }
01487 return *m_change_finder_p;
01488
01489 }
01490
01491 virtual const char* kind() const
01492 { return "sc_inout"; }
01493
01494 protected:
01495
01496 data_type* m_init_val;
01497
01498 public:
01499
01500
01501 void add_trace_internal( sc_trace_file*, const std::string& ) const;
01502
01503 void add_trace( sc_trace_file*, const std::string& ) const;
01504
01505 protected:
01506
01507 void remove_traces() const;
01508
01509 mutable sc_trace_params_vec* m_traces;
01510
01511 private:
01512 mutable sc_event_finder* m_change_finder_p;
01513 mutable sc_event_finder* m_neg_finder_p;
01514 mutable sc_event_finder* m_pos_finder_p;
01515
01519
01520 mutable CHNL_MTX_TYPE_ m_mutex;
01521
01522 private:
01523
01524
01525 sc_inout( const this_type& );
01526
01527 #ifdef __GNUC__
01528
01529
01530
01531
01532 static data_type dummy;
01533 #endif
01534 };
01535
01536
01537
01543 template <>
01544 class sc_inout<sc_dt::sc_logic>
01545 : public sc_port<sc_signal_inout_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
01546 {
01547 public:
01548
01549
01550
01551 typedef sc_dt::sc_logic data_type;
01552
01553 typedef sc_signal_inout_if<data_type> if_type;
01554 typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
01555 typedef sc_inout<data_type> this_type;
01556
01557 typedef sc_signal_in_if<data_type> in_if_type;
01558 typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
01559 typedef if_type inout_if_type;
01560 typedef base_type inout_port_type;
01561
01562 public:
01563
01564
01565
01566 sc_inout()
01567 : base_type(), m_init_val( 0 ), m_traces( 0 ),
01568 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01569 { CHNL_MTX_INIT_( m_mutex ); }
01570
01571 explicit sc_inout( const char* name_ )
01572 : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
01573 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01574 { CHNL_MTX_INIT_( m_mutex ); }
01575
01576 explicit sc_inout( inout_if_type& interface_ )
01577 : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
01578 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01579 { CHNL_MTX_INIT_( m_mutex ); }
01580
01581 sc_inout( const char* name_, inout_if_type& interface_ )
01582 : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
01583 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01584 { CHNL_MTX_INIT_( m_mutex ); }
01585
01586 explicit sc_inout( inout_port_type& parent_ )
01587 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01588 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01589 { CHNL_MTX_INIT_( m_mutex ); }
01590
01591 sc_inout( const char* name_, inout_port_type& parent_ )
01592 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01593 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01594 { CHNL_MTX_INIT_( m_mutex ); }
01595
01596 sc_inout( this_type& parent_ )
01597 : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01598 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01599 { CHNL_MTX_INIT_( m_mutex ); }
01600
01601 sc_inout( const char* name_, this_type& parent_ )
01602 : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01603 m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01604 { CHNL_MTX_INIT_( m_mutex ); }
01605
01606
01607
01608
01609 virtual ~sc_inout();
01610
01611
01612
01613
01614
01615
01616 const sc_event& default_event() const
01617 { return (*this)->default_event(); }
01618
01619
01620
01621
01622 const sc_event& value_changed_event() const
01623 { return (*this)->value_changed_event(); }
01624
01625
01626
01627 const sc_event& posedge_event() const
01628 { return (*this)->posedge_event(); }
01629
01630
01631
01632 const sc_event& negedge_event() const
01633 { return (*this)->negedge_event(); }
01634
01635
01636
01637
01638 const data_type& read() const
01639 { return (*this)->read(); }
01640
01641 operator const data_type& () const
01642 { return (*this)->read(); }
01643
01644
01645
01646
01647 sc_event_finder& pos() const
01648 {
01649
01650 chnl_scoped_lock lock( m_mutex );
01651
01652 if ( !m_pos_finder_p )
01653 {
01654 m_pos_finder_p = new sc_event_finder_t<in_if_type>(
01655 *this, &in_if_type::posedge_event );
01656 }
01657 return *m_pos_finder_p;
01658
01659 }
01660
01661
01662
01663 sc_event_finder& neg() const
01664 {
01665
01666 chnl_scoped_lock lock( m_mutex );
01667
01668 if ( !m_neg_finder_p )
01669 {
01670 m_neg_finder_p = new sc_event_finder_t<in_if_type>(
01671 *this, &in_if_type::negedge_event );
01672 }
01673 return *m_neg_finder_p;
01674
01675 }
01676
01677
01678
01679
01680 bool event() const
01681 { return (*this)->event(); }
01682
01683
01684
01685 bool posedge() const
01686 { return (*this)->posedge(); }
01687
01688
01689
01690 bool negedge() const
01691 { return (*this)->negedge(); }
01692
01693
01694
01695 void write( const data_type& value_ )
01696 { (*this)->write( value_ ); }
01697
01698 this_type& operator = ( const data_type& value_ )
01699 { (*this)->write( value_ ); return *this; }
01700
01701 this_type& operator = ( const in_if_type& interface_ )
01702 { (*this)->write( interface_.read() ); return *this; }
01703
01704 this_type& operator = ( const in_port_type& port_ )
01705 { (*this)->write( port_->read() ); return *this; }
01706
01707 this_type& operator = ( const inout_port_type& port_ )
01708 { (*this)->write( port_->read() ); return *this; }
01709
01710 this_type& operator = ( const this_type& port_ )
01711 { (*this)->write( port_->read() ); return *this; }
01712
01713
01714
01715
01716 void initialize( const data_type& value_ );
01717
01718 void initialize( const in_if_type& interface_ )
01719 { initialize( interface_.read() ); }
01720
01721
01722
01723
01724
01725
01726 virtual void end_of_elaboration();
01727
01728
01729
01730
01731 sc_event_finder& value_changed() const
01732 {
01733
01734 chnl_scoped_lock lock( m_mutex );
01735
01736 if ( !m_change_finder_p )
01737 {
01738 m_change_finder_p = new sc_event_finder_t<in_if_type>(
01739 *this, &in_if_type::value_changed_event );
01740 }
01741 return *m_change_finder_p;
01742
01743 }
01744
01745 virtual const char* kind() const
01746 { return "sc_inout"; }
01747
01748 protected:
01749
01750 data_type* m_init_val;
01751
01752 public:
01753
01754
01755 void add_trace_internal( sc_trace_file*, const std::string& ) const;
01756
01757 void add_trace( sc_trace_file*, const std::string& ) const;
01758
01759 protected:
01760
01761 void remove_traces() const;
01762
01763 mutable sc_trace_params_vec* m_traces;
01764
01765 private:
01766 mutable sc_event_finder* m_change_finder_p;
01767 mutable sc_event_finder* m_neg_finder_p;
01768 mutable sc_event_finder* m_pos_finder_p;
01769
01773
01774 mutable CHNL_MTX_TYPE_ m_mutex;
01775
01776 private:
01777
01778
01779 sc_inout( const this_type& );
01780
01781 #ifdef __GNUC__
01782
01783
01784
01785
01786 static data_type dummy;
01787 #endif
01788 };
01789
01790
01791
01797
01798
01799
01800 template <class T>
01801 class sc_out
01802 : public sc_inout<T>
01803 {
01804 public:
01805
01806
01807
01808 typedef T data_type;
01809
01810 typedef sc_out<data_type> this_type;
01811 typedef sc_inout<data_type> base_type;
01812
01813 typedef typename base_type::in_if_type in_if_type;
01814 typedef typename base_type::in_port_type in_port_type;
01815 typedef typename base_type::inout_if_type inout_if_type;
01816 typedef typename base_type::inout_port_type inout_port_type;
01817
01818 public:
01819
01820
01821
01822 sc_out()
01823 : base_type()
01824 {}
01825
01826 explicit sc_out( const char* name_ )
01827 : base_type( name_ )
01828 {}
01829
01830 explicit sc_out( inout_if_type& interface_ )
01831 : base_type( interface_ )
01832 {}
01833
01834 sc_out( const char* name_, inout_if_type& interface_ )
01835 : base_type( name_, interface_ )
01836 {}
01837
01838 explicit sc_out( inout_port_type& parent_ )
01839 : base_type( parent_ )
01840 {}
01841
01842 sc_out( const char* name_, inout_port_type& parent_ )
01843 : base_type( name_, parent_ )
01844 {}
01845
01846 sc_out( this_type& parent_ )
01847 : base_type( parent_ )
01848 {}
01849
01850 sc_out( const char* name_, this_type& parent_ )
01851 : base_type( name_, parent_ )
01852 {}
01853
01854
01855
01856
01857 virtual ~sc_out()
01858 {}
01859
01860
01861
01862
01863 this_type& operator = ( const data_type& value_ )
01864 { (*this)->write( value_ ); return *this; }
01865
01866 this_type& operator = ( const in_if_type& interface_ )
01867 { (*this)->write( interface_.read() ); return *this; }
01868
01869 this_type& operator = ( const in_port_type& port_ )
01870 { (*this)->write( port_->read() ); return *this; }
01871
01872 this_type& operator = ( const inout_port_type& port_ )
01873 { (*this)->write( port_->read() ); return *this; }
01874
01875 this_type& operator = ( const this_type& port_ )
01876 { (*this)->write( port_->read() ); return *this; }
01877
01878 virtual const char* kind() const
01879 { return "sc_out"; }
01880
01881 private:
01882
01883
01884 sc_out( const this_type& );
01885 };
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895 template <class T>
01896 inline
01897 void
01898 sc_trace(sc_trace_file* tf, const sc_in<T>& port, const std::string& name)
01899 {
01900 const sc_signal_in_if<T>* iface = 0;
01901 if (sc_get_curr_simcontext()->elaboration_done() )
01902 {
01903 iface = DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
01904 }
01905
01906 if ( iface )
01907 sc_trace( tf, iface->read(), name );
01908 else
01909 port.add_trace_internal( tf, name );
01910 }
01911
01912 template <class T>
01913 inline
01914 void
01915 sc_trace( sc_trace_file* tf, const sc_inout<T>& port,
01916 const std::string& name )
01917 {
01918 const sc_signal_in_if<T>* iface = 0;
01919 if (sc_get_curr_simcontext()->elaboration_done() )
01920 {
01921 iface =DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
01922 }
01923
01924 if ( iface )
01925 sc_trace( tf, iface->read(), name );
01926 else
01927 port.add_trace_internal( tf, name );
01928 }
01929
01930 }
01931
01932 #undef SC_VIRTUAL_
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034 #endif
02035
02036