sc_signal_ports.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_signal_ports.h -- The sc_signal<T> port classes.
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024   Change log appears at end of file
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 namespace sc_core {
00038 
00039 // ----------------------------------------------------------------------------
00040 //  STRUCT : sc_trace_params
00041 //
00042 //  Struct for storing the trace file and object name of an sc_trace call.
00043 //  FOR INTERNAL USE ONLY!
00044 // ----------------------------------------------------------------------------
00045 
00046 extern void sc_deprecated_add_trace();
00047 
00048 struct sc_trace_params
00049 {
00050     sc_trace_file*        tf;
00051     std::string      name;
00052 
00053     sc_trace_params( sc_trace_file* tf_, const std::string& name_ )
00054     : tf( tf_ ), name( name_ )
00055     {}
00056 };
00057 
00058 
00059 typedef std::vector<sc_trace_params*> sc_trace_params_vec;
00060 
00061 
00062 // ----------------------------------------------------------------------------
00063 //  CLASS : sc_in<T>
00064 //
00065 //  The sc_signal<T> input port class.
00066 // ----------------------------------------------------------------------------
00067 
00068 template <class T>
00069 class sc_in
00070 : public sc_port<sc_signal_in_if<T>,1,SC_ONE_OR_MORE_BOUND>
00071 {
00072 public:
00073 
00074     // typedefs
00075 
00076     typedef T                                             data_type;
00077 
00078     typedef sc_signal_in_if<data_type>                    if_type;
00079     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>       base_type;
00080     typedef sc_in<data_type>                              this_type;
00081 
00082     typedef if_type                                       in_if_type;
00083     typedef base_type                                     in_port_type;
00084     typedef sc_signal_inout_if<data_type>                 inout_if_type;
00085     typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
00086 
00087 public:
00088 
00089     // constructors
00090 
00091     sc_in()
00092     : base_type(), m_traces( 0 ),
00093       m_change_finder_p(0)
00094     {}
00095 
00096     explicit sc_in( const char* name_ )
00097     : base_type( name_ ), m_traces( 0 ),
00098       m_change_finder_p(0)
00099     {}
00100 
00101     explicit sc_in( const in_if_type& interface_ )
00102         : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00103       m_change_finder_p(0)
00104         {}
00105 
00106     sc_in( const char* name_, const in_if_type& interface_ )
00107     : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00108       m_change_finder_p(0)
00109     {}
00110 
00111     explicit sc_in( in_port_type& parent_ )
00112     : base_type( parent_ ), m_traces( 0 ),
00113       m_change_finder_p(0)
00114     {}
00115 
00116     sc_in( const char* name_, in_port_type& parent_ )
00117     : base_type( name_, parent_ ), m_traces( 0 ),
00118       m_change_finder_p(0)
00119     {}
00120 
00121     explicit sc_in( inout_port_type& parent_ )
00122     : base_type(), m_traces( 0 ),
00123       m_change_finder_p(0)
00124     { sc_port_base::bind( parent_ ); }
00125 
00126     sc_in( const char* name_, inout_port_type& parent_ )
00127     : base_type( name_ ), m_traces( 0 ),
00128       m_change_finder_p(0)
00129     { sc_port_base::bind( parent_ ); }
00130 
00131     sc_in( this_type& parent_ )
00132     : base_type( parent_ ), m_traces( 0 ),
00133       m_change_finder_p(0)
00134     {}
00135 
00136     sc_in( const char* name_, this_type& parent_ )
00137     : base_type( name_, parent_ ), m_traces( 0 ),
00138       m_change_finder_p(0)
00139     {}
00140 
00141 
00142     // destructor
00143 
00144     virtual ~sc_in()
00145     {
00146         remove_traces();
00147         if ( m_change_finder_p ) delete m_change_finder_p;
00148     }
00149 
00150 
00151     // bind to in interface
00152 
00153     void bind( const in_if_type& interface_ )
00154     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00155 
00156     void operator () ( const in_if_type& interface_ )
00157     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00158 
00159 
00160     // bind to parent in port
00161 
00162     void bind( in_port_type& parent_ )
00163         { sc_port_base::bind( parent_ ); }
00164 
00165     void operator () ( in_port_type& parent_ )
00166         { sc_port_base::bind( parent_ ); }
00167 
00168 
00169     // bind to parent inout port
00170 
00171     void bind( inout_port_type& parent_ )
00172     { sc_port_base::bind( parent_ ); }
00173 
00174     void operator () ( inout_port_type& parent_ )
00175     { sc_port_base::bind( parent_ ); }
00176 
00177 
00178     // interface access shortcut methods
00179 
00180     // get the default event
00181 
00182     const sc_event& default_event() const
00183     { return (*this)->default_event(); }
00184 
00185 
00186     // get the value changed event
00187 
00188     const sc_event& value_changed_event() const
00189     { return (*this)->value_changed_event(); }
00190 
00191 
00192     // read the current value
00193 
00194     const data_type& read() const
00195     { return (*this)->read(); }
00196 
00197     operator const data_type& () const
00198     { return (*this)->read(); }
00199 
00200 
00201     // was there a value changed event?
00202 
00203     bool event() const
00204     { return (*this)->event(); }
00205 
00206 
00207     // (other) event finder method(s)
00208 
00209     sc_event_finder& value_changed() const
00210     {
00211         if ( !m_change_finder_p )
00212     {
00213         m_change_finder_p = new sc_event_finder_t<in_if_type>(
00214             *this, &in_if_type::value_changed_event );
00215     }
00216     return *m_change_finder_p;
00217     }
00218 
00219 
00220     // called when elaboration is done
00221     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
00222     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
00223 
00224     virtual void end_of_elaboration();
00225 
00226     virtual const char* kind() const
00227         { return "sc_in"; }
00228 
00229 
00230     void add_trace( sc_trace_file*, const std::string& ) const;
00231 
00232     // called by sc_trace
00233     void add_trace_internal( sc_trace_file*, const std::string& ) const;
00234 
00235 protected:
00236 
00237     void remove_traces() const;
00238 
00239     mutable sc_trace_params_vec* m_traces;
00240 
00241 protected:
00242 
00243     // called by pbind (for internal use only)
00244     virtual int vbind( sc_interface& );
00245     virtual int vbind( sc_port_base& );
00246 
00247 private:
00248   mutable sc_event_finder* m_change_finder_p;
00249 
00250 private:
00251 
00252     // disabled
00253     sc_in( const this_type& );
00254     this_type& operator = ( const this_type& );
00255 
00256 #ifdef __GNUC__
00257     // Needed to circumvent a problem in the g++-2.95.2 compiler:
00258     // This unused variable forces the compiler to instantiate
00259     // an object of T template so an implicit conversion from
00260     // read() to a C++ intrinsic data type will work.
00261     static data_type dummy;
00262 #endif
00263 };
00264 
00265 template<typename T>
00266 ::std::ostream& operator << ( ::std::ostream& os, const sc_in<T>& a )
00267 {
00268     return os << a->read();
00269 }
00270 
00271 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00272 
00273 
00274 // called when elaboration is done
00275 
00276 template <class T>
00277 inline
00278 void
00279 sc_in<T>::end_of_elaboration()
00280 {
00281     if( m_traces != 0 ) {
00282     for( int i = 0; i < (int)m_traces->size(); ++ i ) {
00283         sc_trace_params* p = (*m_traces)[i];
00284         in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
00285         sc_trace( p->tf, iface->read(), p->name );
00286     }
00287     remove_traces();
00288     }
00289 }
00290 
00291 
00292 // called by sc_trace
00293 
00294 template <class T>
00295 inline
00296 void
00297 sc_in<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_ ) 
00298 const
00299 {
00300     if( tf_ != 0 ) {
00301     if( m_traces == 0 ) {
00302         m_traces = new sc_trace_params_vec;
00303     }
00304     m_traces->push_back( new sc_trace_params( tf_, name_ ) );
00305     }
00306 }
00307 
00308 template <class T>
00309 inline
00310 void
00311 sc_in<T>::add_trace( sc_trace_file* tf_, const std::string& name_ ) 
00312 const
00313 {
00314     sc_deprecated_add_trace();
00315     add_trace_internal(tf_, name_);
00316 }
00317 
00318 template <class T>
00319 inline
00320 void
00321 sc_in<T>::remove_traces() const
00322 {
00323     if( m_traces != 0 ) {
00324     for( int i = (int)m_traces->size() - 1; i >= 0; -- i ) {
00325         delete (*m_traces)[i];
00326     }
00327     delete m_traces;
00328     m_traces = 0;
00329     }
00330 }
00331 
00332 
00333 // called by pbind (for internal use only)
00334 
00335 template <class T>
00336 inline
00337 int
00338 sc_in<T>::vbind( sc_interface& interface_ )
00339 {
00340     return sc_port_b<if_type>::vbind( interface_ );
00341 }
00342 
00343 template <class T>
00344 inline
00345 int
00346 sc_in<T>::vbind( sc_port_base& parent_ )
00347 {
00348     in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
00349     if( in_parent != 0 ) {
00350     sc_port_base::bind( *in_parent );
00351     return 0;
00352     }
00353     inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
00354     if( inout_parent != 0 ) {
00355     sc_port_base::bind( *inout_parent );
00356     return 0;
00357     }
00358     // type mismatch
00359     return 2;
00360 }
00361 
00362 
00363 // ----------------------------------------------------------------------------
00364 //  CLASS : sc_in<bool>
00365 //
00366 //  Specialization of sc_in<T> for type bool.
00367 // ----------------------------------------------------------------------------
00368 
00369 template <>
00370 class sc_in<bool> : 
00371     public sc_port<sc_signal_in_if<bool>,1,SC_ONE_OR_MORE_BOUND>
00372 {
00373 public:
00374 
00375     // typedefs
00376 
00377     typedef bool                                           data_type;
00378 
00379     typedef sc_signal_in_if<data_type>                     if_type;
00380     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>        base_type;
00381     typedef sc_in<data_type>                               this_type;
00382 
00383     typedef if_type                                        in_if_type;
00384     typedef base_type                                      in_port_type;
00385     typedef sc_signal_inout_if<data_type>                  inout_if_type;
00386     typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND>  inout_port_type;
00387 
00388 public:
00389 
00390     // constructors
00391 
00392     sc_in()
00393     : base_type(), m_traces( 0 ), m_change_finder_p(0), 
00394       m_neg_finder_p(0), m_pos_finder_p(0)
00395     {}
00396 
00397     explicit sc_in( const char* name_ )
00398     : base_type( name_ ), m_traces( 0 ), m_change_finder_p(0), 
00399       m_neg_finder_p(0), m_pos_finder_p(0)
00400     {}
00401 
00402     explicit sc_in( const in_if_type& interface_ )
00403     : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ), 
00404       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00405     {}
00406 
00407     sc_in( const char* name_, const in_if_type& interface_ )
00408     : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00409       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00410     {}
00411 
00412     explicit sc_in( in_port_type& parent_ )
00413     : base_type( parent_ ), m_traces( 0 ),
00414       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00415     {}
00416 
00417     sc_in( const char* name_, in_port_type& parent_ )
00418     : base_type( name_, parent_ ), m_traces( 0 ),
00419       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00420     {}
00421 
00422     explicit sc_in( inout_port_type& parent_ )
00423     : base_type(), m_traces( 0 ),
00424       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00425     { sc_port_base::bind( parent_ ); }
00426 
00427     sc_in( const char* name_, inout_port_type& parent_ )
00428     : base_type( name_ ), m_traces( 0 ),
00429       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00430     { sc_port_base::bind( parent_ ); }
00431 
00432     sc_in( this_type& parent_ )
00433     : base_type( parent_ ), m_traces( 0 ),
00434       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00435     {}
00436 
00437 #if defined(TESTING)
00438     sc_in( const this_type& parent_ )
00439     : base_type( *(in_if_type*)parent_.get_interface() ) , m_traces( 0 ),
00440       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00441     {}
00442 #endif 
00443 
00444     sc_in( const char* name_, this_type& parent_ )
00445     : base_type( name_, parent_ ), m_traces( 0 ),
00446       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00447     {}
00448 
00449 
00450     // destructor
00451 
00452     virtual ~sc_in()
00453     {
00454         remove_traces();
00455         if ( m_change_finder_p ) delete m_change_finder_p;
00456         if ( m_neg_finder_p ) delete m_neg_finder_p;
00457         if ( m_pos_finder_p ) delete m_pos_finder_p;
00458     }
00459 
00460 
00461     // bind to in interface
00462 
00463     void bind( const in_if_type& interface_ )
00464     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00465 
00466     void operator () ( const in_if_type& interface_ )
00467     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00468 
00469 
00470     // bind to parent in port
00471 
00472     void bind( in_port_type& parent_ )
00473         { sc_port_base::bind( parent_ ); }
00474 
00475     void operator () ( in_port_type& parent_ )
00476         { sc_port_base::bind( parent_ ); }
00477 
00478 
00479     // bind to parent inout port
00480 
00481     void bind( inout_port_type& parent_ )
00482     { sc_port_base::bind( parent_ ); }
00483 
00484     void operator () ( inout_port_type& parent_ )
00485     { sc_port_base::bind( parent_ ); }
00486 
00487 
00488     // interface access shortcut methods
00489 
00490     // get the default event
00491 
00492     const sc_event& default_event() const
00493     { return (*this)->default_event(); }
00494 
00495 
00496     // get the value changed event
00497 
00498     const sc_event& value_changed_event() const
00499     { return (*this)->value_changed_event(); }
00500 
00501     // get the positive edge event
00502 
00503     const sc_event& posedge_event() const
00504     { return (*this)->posedge_event(); }
00505 
00506     // get the negative edge event
00507 
00508     const sc_event& negedge_event() const
00509     { return (*this)->negedge_event(); }
00510 
00511 
00512     // read the current value
00513 
00514     const data_type& read() const
00515     { return (*this)->read(); }
00516 
00517     operator const data_type& () const
00518     { return (*this)->read(); }
00519 
00520 
00521     // use for positive edge sensitivity
00522 
00523     sc_event_finder& pos() const
00524     {
00525         if ( !m_pos_finder_p )
00526     {
00527         m_pos_finder_p = new sc_event_finder_t<in_if_type>(
00528             *this, &in_if_type::posedge_event );
00529     } 
00530     return *m_pos_finder_p;
00531     }
00532 
00533     // use for negative edge sensitivity
00534 
00535     sc_event_finder& neg() const
00536     {
00537         if ( !m_neg_finder_p )
00538     {
00539         m_neg_finder_p = new sc_event_finder_t<in_if_type>(
00540             *this, &in_if_type::negedge_event );
00541     } 
00542     return *m_neg_finder_p;
00543     }
00544 
00545 
00546     // was there a value changed event?
00547 
00548     bool event() const
00549     { return (*this)->event(); }
00550 
00551     // was there a positive edge event?
00552 
00553     bool posedge() const
00554         { return (*this)->posedge(); }
00555 
00556     // was there a negative edge event?
00557 
00558     bool negedge() const
00559         { return (*this)->negedge(); }
00560 
00561     // (other) event finder method(s)
00562 
00563     sc_event_finder& value_changed() const
00564     {
00565         if ( !m_change_finder_p )
00566     {
00567         m_change_finder_p = new sc_event_finder_t<in_if_type>(
00568             *this, &in_if_type::value_changed_event );
00569     }
00570     return *m_change_finder_p;
00571     }
00572 
00573 
00574     // called when elaboration is done
00575     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
00576     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
00577 
00578     virtual void end_of_elaboration();
00579 
00580     virtual const char* kind() const
00581         { return "sc_in"; }
00582 
00583 
00584     void add_trace( sc_trace_file*, const std::string& ) const;
00585 
00586     // called by sc_trace
00587     void add_trace_internal( sc_trace_file*, const std::string& ) const;
00588 
00589 protected:
00590 
00591     void remove_traces() const;
00592 
00593     mutable sc_trace_params_vec* m_traces;
00594 
00595 protected:
00596 
00597     // called by pbind (for internal use only)
00598     virtual int vbind( sc_interface& );
00599     virtual int vbind( sc_port_base& );
00600 
00601 private:
00602   mutable sc_event_finder* m_change_finder_p;
00603   mutable sc_event_finder* m_neg_finder_p;
00604   mutable sc_event_finder* m_pos_finder_p;
00605 
00606 private:
00607 
00608     // disabled
00609 #if defined(TESTING)
00610 #else
00611     sc_in( const this_type& );
00612 #endif 
00613     this_type& operator = ( const this_type& );
00614 
00615 #ifdef __GNUC__
00616     // Needed to circumvent a problem in the g++-2.95.2 compiler:
00617     // This unused variable forces the compiler to instantiate
00618     // an object of T template so an implicit conversion from
00619     // read() to a C++ intrinsic data type will work.
00620     static data_type dummy;
00621 #endif
00622 };
00623 
00624 
00625 // ----------------------------------------------------------------------------
00626 //  CLASS : sc_in<sc_dt::sc_logic>
00627 //
00628 //  Specialization of sc_in<T> for type sc_dt::sc_logic.
00629 // ----------------------------------------------------------------------------
00630 
00631 template <>
00632 class sc_in<sc_dt::sc_logic>
00633 : public sc_port<sc_signal_in_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
00634 {
00635 public:
00636 
00637     // typedefs
00638 
00639     typedef sc_dt::sc_logic                               data_type;
00640 
00641     typedef sc_signal_in_if<data_type>                    if_type;
00642     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>       base_type;
00643     typedef sc_in<data_type>                              this_type;
00644 
00645     typedef if_type                                       in_if_type;
00646     typedef base_type                                     in_port_type;
00647     typedef sc_signal_inout_if<data_type>                 inout_if_type;
00648     typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
00649 
00650 public:
00651 
00652     // constructors
00653 
00654     sc_in()
00655     : base_type(), m_traces( 0 ),
00656       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00657     {}
00658 
00659     explicit sc_in( const char* name_ )
00660     : base_type( name_ ), m_traces( 0 ),
00661       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00662     {}
00663 
00664     explicit sc_in( const in_if_type& interface_ )
00665     : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00666       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00667     {}
00668 
00669     sc_in( const char* name_, const in_if_type& interface_ )
00670     : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
00671       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00672     {}
00673 
00674     explicit sc_in( in_port_type& parent_ )
00675     : base_type( parent_ ), m_traces( 0 ),
00676       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00677     {}
00678 
00679     sc_in( const char* name_, in_port_type& parent_ )
00680     : base_type( name_, parent_ ), m_traces( 0 ),
00681       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00682     {}
00683 
00684     explicit sc_in( inout_port_type& parent_ )
00685     : base_type(), m_traces( 0 ),
00686       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00687     { sc_port_base::bind( parent_ ); }
00688 
00689     sc_in( const char* name_, inout_port_type& parent_ )
00690     : base_type( name_ ), m_traces( 0 ),
00691       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00692     { sc_port_base::bind( parent_ ); }
00693 
00694     sc_in( this_type& parent_ )
00695     : base_type( parent_ ), m_traces( 0 ),
00696       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00697     {}
00698 
00699     sc_in( const char* name_, this_type& parent_ )
00700     : base_type( name_, parent_ ), m_traces( 0 ),
00701       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
00702     {}
00703 
00704 
00705     // destructor
00706 
00707     virtual ~sc_in()
00708     {
00709         remove_traces();
00710         if ( m_change_finder_p ) delete m_change_finder_p;
00711         if ( m_neg_finder_p ) delete m_neg_finder_p;
00712         if ( m_pos_finder_p ) delete m_pos_finder_p;
00713     }
00714 
00715 
00716     // bind to in interface
00717 
00718     void bind( const in_if_type& interface_ )
00719     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00720 
00721     void operator () ( const in_if_type& interface_ )
00722     { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
00723 
00724 
00725     // bind to parent in port
00726 
00727     void bind( in_port_type& parent_ )
00728         { sc_port_base::bind( parent_ ); }
00729 
00730     void operator () ( in_port_type& parent_ )
00731         { sc_port_base::bind( parent_ ); }
00732 
00733 
00734     // bind to parent inout port
00735 
00736     void bind( inout_port_type& parent_ )
00737     { sc_port_base::bind( parent_ ); }
00738 
00739     void operator () ( inout_port_type& parent_ )
00740     { sc_port_base::bind( parent_ ); }
00741 
00742 
00743     // interface access shortcut methods
00744 
00745     // get the default event
00746 
00747     const sc_event& default_event() const
00748     { return (*this)->default_event(); }
00749 
00750 
00751     // get the value changed event
00752 
00753     const sc_event& value_changed_event() const
00754     { return (*this)->value_changed_event(); }
00755 
00756     // get the positive edge event
00757 
00758     const sc_event& posedge_event() const
00759     { return (*this)->posedge_event(); }
00760 
00761     // get the negative edge event
00762 
00763     const sc_event& negedge_event() const
00764     { return (*this)->negedge_event(); }
00765 
00766 
00767     // read the current value
00768 
00769     const data_type& read() const
00770     { return (*this)->read(); }
00771 
00772     operator const data_type& () const
00773     { return (*this)->read(); }
00774 
00775 
00776     // use for positive edge sensitivity
00777 
00778     sc_event_finder& pos() const
00779     {
00780         if ( !m_pos_finder_p )
00781     {
00782         m_pos_finder_p = new sc_event_finder_t<in_if_type>(
00783             *this, &in_if_type::posedge_event );
00784     } 
00785     return *m_pos_finder_p;
00786     }
00787 
00788     // use for negative edge sensitivity
00789 
00790     sc_event_finder& neg() const
00791     {
00792         if ( !m_neg_finder_p )
00793     {
00794         m_neg_finder_p = new sc_event_finder_t<in_if_type>(
00795             *this, &in_if_type::negedge_event );
00796     } 
00797     return *m_neg_finder_p;
00798     }
00799 
00800 
00801     // was there a value changed event?
00802 
00803     bool event() const
00804     { return (*this)->event(); }
00805 
00806     // was there a positive edge event?
00807 
00808     bool posedge() const
00809         { return (*this)->posedge(); }
00810 
00811     // was there a negative edge event?
00812 
00813     bool negedge() const
00814         { return (*this)->negedge(); }
00815 
00816     // (other) event finder method(s)
00817 
00818     sc_event_finder& value_changed() const
00819     {
00820         if ( !m_change_finder_p )
00821     {
00822         m_change_finder_p = new sc_event_finder_t<in_if_type>(
00823             *this, &in_if_type::value_changed_event );
00824     }
00825     return *m_change_finder_p;
00826     }
00827 
00828 
00829     // called when elaboration is done
00830     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
00831     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
00832 
00833     virtual void end_of_elaboration();
00834 
00835     virtual const char* kind() const
00836         { return "sc_in"; }
00837 
00838 
00839     void add_trace( sc_trace_file*, const std::string& ) const;
00840 
00841     // called by sc_trace
00842     void add_trace_internal( sc_trace_file*, const std::string& ) const;
00843 
00844 protected:
00845 
00846     void remove_traces() const;
00847 
00848     mutable sc_trace_params_vec* m_traces;
00849 
00850 protected:
00851 
00852     // called by pbind (for internal use only)
00853     virtual int vbind( sc_interface& );
00854     virtual int vbind( sc_port_base& );
00855 
00856 private:
00857   mutable sc_event_finder* m_change_finder_p;
00858   mutable sc_event_finder* m_neg_finder_p;
00859   mutable sc_event_finder* m_pos_finder_p;
00860 
00861 private:
00862 
00863     // disabled
00864     sc_in( const this_type& );
00865     this_type& operator = ( const this_type& );
00866 
00867 #ifdef __GNUC__
00868     // Needed to circumvent a problem in the g++-2.95.2 compiler:
00869     // This unused variable forces the compiler to instantiate
00870     // an object of T template so an implicit conversion from
00871     // read() to a C++ intrinsic data type will work.
00872     static data_type dummy;
00873 #endif
00874 };
00875 
00876 
00877 // ----------------------------------------------------------------------------
00878 //  CLASS : sc_inout<T>
00879 //
00880 //  The sc_signal<T> input/output port class.
00881 // ----------------------------------------------------------------------------
00882 
00883 template <class T>
00884 class sc_inout
00885 : public sc_port<sc_signal_inout_if<T>,1,SC_ONE_OR_MORE_BOUND>
00886 {
00887 public:
00888 
00889     // typedefs
00890 
00891     typedef T                                          data_type;
00892 
00893     typedef sc_signal_inout_if<data_type>              if_type;
00894     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>    base_type;
00895     typedef sc_inout<data_type>                        this_type;
00896 
00897     typedef sc_signal_in_if<data_type>                 in_if_type;
00898     typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
00899     typedef if_type                                    inout_if_type;
00900     typedef base_type                                  inout_port_type;
00901 
00902 public:
00903 
00904     // constructors
00905 
00906     sc_inout()
00907     : base_type(), m_init_val( 0 ), m_traces( 0 ),
00908       m_change_finder_p(0)
00909     {}
00910 
00911     explicit sc_inout( const char* name_ )
00912     : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
00913       m_change_finder_p(0)
00914     {}
00915 
00916     explicit sc_inout( inout_if_type& interface_ )
00917     : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
00918       m_change_finder_p(0)
00919     {}
00920 
00921     sc_inout( const char* name_, inout_if_type& interface_ )
00922     : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
00923       m_change_finder_p(0)
00924     {}
00925 
00926     explicit sc_inout( inout_port_type& parent_ )
00927     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
00928       m_change_finder_p(0)
00929     {}
00930 
00931     sc_inout( const char* name_, inout_port_type& parent_ )
00932     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
00933       m_change_finder_p(0)
00934     {}
00935 
00936     sc_inout( this_type& parent_ )
00937     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
00938       m_change_finder_p(0)
00939     {}
00940 
00941     sc_inout( const char* name_, this_type& parent_ )
00942     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
00943       m_change_finder_p(0)
00944     {}
00945 
00946 
00947     // destructor
00948 
00949     virtual ~sc_inout();
00950 
00951 
00952     // interface access shortcut methods
00953 
00954     // get the default event
00955 
00956     const sc_event& default_event() const
00957     { return (*this)->default_event(); }
00958 
00959 
00960     // get the value changed event
00961 
00962     const sc_event& value_changed_event() const
00963     { return (*this)->value_changed_event(); }
00964 
00965 
00966     // read the current value
00967 
00968     const data_type& read() const
00969     { return (*this)->read(); }
00970 
00971     operator const data_type& () const
00972     { return (*this)->read(); }
00973 
00974 
00975     // was there a value changed event?
00976 
00977     bool event() const
00978     { return (*this)->event(); }
00979 
00980 
00981     // write the new value
00982 
00983     void write( const data_type& value_ )
00984     { (*this)->write( value_ ); }
00985 
00986     this_type& operator = ( const data_type& value_ )
00987     { (*this)->write( value_ ); return *this; }
00988 
00989     this_type& operator = ( const in_if_type& interface_ )
00990     { (*this)->write( interface_.read() ); return *this; }
00991 
00992     this_type& operator = ( const in_port_type& port_ )
00993     { (*this)->write( port_->read() ); return *this; }
00994 
00995     this_type& operator = ( const inout_port_type& port_ )
00996     { (*this)->write( port_->read() ); return *this; }
00997 
00998     this_type& operator = ( const this_type& port_ )
00999     { (*this)->write( port_->read() ); return *this; }
01000 
01001 
01002     // set initial value (can also be called when port is not bound yet)
01003 
01004     void initialize( const data_type& value_ );
01005 
01006     void initialize( const in_if_type& interface_ )
01007     { initialize( interface_.read() ); }
01008 
01009 
01010     // called when elaboration is done
01011     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
01012     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
01013 
01014     virtual void end_of_elaboration();
01015 
01016 
01017     // (other) event finder method(s)
01018 
01019     sc_event_finder& value_changed() const
01020     {
01021         if ( !m_change_finder_p )
01022     {
01023         m_change_finder_p = new sc_event_finder_t<in_if_type>(
01024             *this, &in_if_type::value_changed_event );
01025     }
01026     return *m_change_finder_p;
01027     }
01028 
01029     virtual const char* kind() const
01030         { return "sc_inout"; }
01031 
01032 protected:
01033 
01034     data_type* m_init_val;
01035 
01036 public:
01037 
01038     // called by sc_trace
01039     void add_trace_internal( sc_trace_file*, const std::string& ) const;
01040 
01041     void add_trace( sc_trace_file*, const std::string& ) const;
01042 
01043 protected:
01044 
01045     void remove_traces() const;
01046 
01047     mutable sc_trace_params_vec* m_traces;
01048 
01049 private:
01050   mutable sc_event_finder* m_change_finder_p;
01051 
01052 private:
01053 
01054     // disabled
01055     sc_inout( const this_type& );
01056 
01057 #ifdef __GNUC__
01058     // Needed to circumvent a problem in the g++-2.95.2 compiler:
01059     // This unused variable forces the compiler to instantiate
01060     // an object of T template so an implicit conversion from
01061     // read() to a C++ intrinsic data type will work.
01062     static data_type dummy;
01063 #endif
01064 };
01065 
01066 template<typename T>
01067 ::std::ostream& operator << ( ::std::ostream& os, const sc_inout<T>& a )
01068 {
01069     return os << a->read();
01070 }
01071 
01072 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01073 
01074 
01075 // destructor
01076 
01077 template <class T>
01078 inline
01079 sc_inout<T>::~sc_inout()
01080 {
01081     if ( m_change_finder_p ) delete m_change_finder_p;
01082     if( m_init_val != 0 ) {
01083     delete m_init_val;
01084     }
01085     remove_traces();
01086 }
01087 
01088 
01089 // set initial value (can also be called when port is not bound yet)
01090 
01091 template <class T>
01092 inline
01093 void
01094 sc_inout<T>::initialize( const data_type& value_ )
01095 {
01096     inout_if_type* iface = DCAST<inout_if_type*>( this->get_interface() );
01097     if( iface != 0 ) {
01098     iface->write( value_ );
01099     } else {
01100     if( m_init_val == 0 ) {
01101         m_init_val = new data_type;
01102     }
01103     *m_init_val = value_;
01104     }
01105 }
01106 
01107 
01108 // called when elaboration is done
01109 
01110 template <class T>
01111 inline
01112 void
01113 sc_inout<T>::end_of_elaboration()
01114 {
01115     if( m_init_val != 0 ) {
01116     write( *m_init_val );
01117     delete m_init_val;
01118     m_init_val = 0;
01119     }
01120     if( m_traces != 0 ) {
01121     for( int i = 0; i < (int)m_traces->size(); ++ i ) {
01122         sc_trace_params* p = (*m_traces)[i];
01123         in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
01124         sc_trace( p->tf, iface->read(), p->name );
01125     }
01126     remove_traces();
01127     }
01128 }
01129 
01130 
01131 // called by sc_trace
01132 
01133 template <class T>
01134 inline
01135 void
01136 sc_inout<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_) 
01137 const
01138 {
01139     if( tf_ != 0 ) {
01140         if( m_traces == 0 ) {
01141             m_traces = new sc_trace_params_vec;
01142         }
01143         m_traces->push_back( new sc_trace_params( tf_, name_ ) );
01144     }
01145 }
01146 
01147 template <class T>
01148 inline
01149 void
01150 sc_inout<T>::add_trace( sc_trace_file* tf_, const std::string& name_) const
01151 {
01152     sc_deprecated_add_trace();
01153     add_trace_internal(tf_, name_);
01154 }
01155 
01156 template <class T>
01157 inline
01158 void
01159 sc_inout<T>::remove_traces() const
01160 {
01161     if( m_traces != 0 ) {
01162         for( int i = m_traces->size() - 1; i >= 0; -- i ) {
01163             delete (*m_traces)[i];
01164         }
01165         delete m_traces;
01166         m_traces = 0;
01167     }
01168 }
01169 
01170 
01171 // ----------------------------------------------------------------------------
01172 //  CLASS : sc_inout<bool>
01173 //
01174 //  Specialization of sc_inout<T> for type bool.
01175 // ----------------------------------------------------------------------------
01176 
01177 template <>
01178 class sc_inout<bool> : 
01179     public sc_port<sc_signal_inout_if<bool>,1,SC_ONE_OR_MORE_BOUND>
01180 {
01181 public:
01182 
01183     // typedefs
01184 
01185     typedef bool                                       data_type;
01186 
01187     typedef sc_signal_inout_if<data_type>              if_type;
01188     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>    base_type;
01189     typedef sc_inout<data_type>                        this_type;
01190 
01191     typedef sc_signal_in_if<data_type>                 in_if_type;
01192     typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
01193     typedef if_type                                    inout_if_type;
01194     typedef base_type                                  inout_port_type;
01195 
01196 public:
01197 
01198     // constructors
01199 
01200     sc_inout()
01201     : base_type(), m_init_val( 0 ), m_traces( 0 ),
01202       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01203     {}
01204 
01205     explicit sc_inout( const char* name_ )
01206     : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
01207       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01208     {}
01209 
01210     explicit sc_inout( inout_if_type& interface_ )
01211     : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
01212       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01213     {}
01214 
01215     sc_inout( const char* name_, inout_if_type& interface_ )
01216     : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
01217       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01218     {}
01219 
01220     explicit sc_inout( inout_port_type& parent_ )
01221     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01222       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01223     {}
01224 
01225     sc_inout( const char* name_, inout_port_type& parent_ )
01226     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01227       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01228     {}
01229 
01230     sc_inout( this_type& parent_ )
01231     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01232       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01233     {}
01234 
01235     sc_inout( const char* name_, this_type& parent_ )
01236     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01237       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01238     {}
01239 
01240 
01241     // destructor
01242 
01243     virtual ~sc_inout();
01244 
01245 
01246     // interface access shortcut methods
01247 
01248     // get the default event
01249 
01250     const sc_event& default_event() const
01251     { return (*this)->default_event(); }
01252 
01253 
01254     // get the value changed event
01255 
01256     const sc_event& value_changed_event() const
01257     { return (*this)->value_changed_event(); }
01258 
01259     // get the positive edge event
01260 
01261     const sc_event& posedge_event() const
01262     { return (*this)->posedge_event(); }
01263 
01264     // get the negative edge event
01265 
01266     const sc_event& negedge_event() const
01267     { return (*this)->negedge_event(); }
01268 
01269 
01270     // read the current value
01271 
01272     const data_type& read() const
01273     { return (*this)->read(); }
01274 
01275     operator const data_type& () const
01276     { return (*this)->read(); }
01277 
01278 
01279     // use for positive edge sensitivity
01280 
01281     sc_event_finder& pos() const
01282     {
01283         if ( !m_pos_finder_p )
01284     {
01285         m_pos_finder_p = new sc_event_finder_t<in_if_type>(
01286             *this, &in_if_type::posedge_event );
01287     } 
01288     return *m_pos_finder_p;
01289     }
01290 
01291     // use for negative edge sensitivity
01292 
01293     sc_event_finder& neg() const
01294     {
01295         if ( !m_neg_finder_p )
01296     {
01297         m_neg_finder_p = new sc_event_finder_t<in_if_type>(
01298             *this, &in_if_type::negedge_event );
01299     } 
01300     return *m_neg_finder_p;
01301     }
01302 
01303 
01304     // was there a value changed event?
01305 
01306     bool event() const
01307     { return (*this)->event(); }
01308 
01309     // was there a positive edge event?
01310 
01311     bool posedge() const
01312         { return (*this)->posedge(); }
01313 
01314     // was there a negative edge event?
01315 
01316     bool negedge() const
01317         { return (*this)->negedge(); }
01318 
01319     // write the new value
01320 
01321     void write( const data_type& value_ )
01322     { (*this)->write( value_ ); }
01323 
01324     this_type& operator = ( const data_type& value_ )
01325     { (*this)->write( value_ ); return *this; }
01326 
01327     this_type& operator = ( const in_if_type& interface_ )
01328     { (*this)->write( interface_.read() ); return *this; }
01329 
01330     this_type& operator = ( const in_port_type& port_ )
01331     { (*this)->write( port_->read() ); return *this; }
01332 
01333     this_type& operator = ( const inout_port_type& port_ )
01334     { (*this)->write( port_->read() ); return *this; }
01335 
01336     this_type& operator = ( const this_type& port_ )
01337     { (*this)->write( port_->read() ); return *this; }
01338 
01339 
01340     // set initial value (can also be called when port is not bound yet)
01341 
01342     void initialize( const data_type& value_ );
01343 
01344     void initialize( const in_if_type& interface_ )
01345     { initialize( interface_.read() ); }
01346 
01347 
01348     // called when elaboration is done
01349     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
01350     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
01351 
01352     virtual void end_of_elaboration();
01353 
01354 
01355     // (other) event finder method(s)
01356 
01357     sc_event_finder& value_changed() const
01358     {
01359         if ( !m_change_finder_p )
01360     {
01361         m_change_finder_p = new sc_event_finder_t<in_if_type>(
01362             *this, &in_if_type::value_changed_event );
01363     }
01364     return *m_change_finder_p;
01365     }
01366 
01367     virtual const char* kind() const
01368         { return "sc_inout"; }
01369 
01370 protected:
01371 
01372     data_type* m_init_val;
01373 
01374 public:
01375 
01376     // called by sc_trace
01377     void add_trace_internal( sc_trace_file*, const std::string& ) const;
01378 
01379     void add_trace( sc_trace_file*, const std::string& ) const;
01380 
01381 protected:
01382 
01383     void remove_traces() const;
01384 
01385     mutable sc_trace_params_vec* m_traces;
01386 
01387 private:
01388   mutable sc_event_finder* m_change_finder_p;
01389   mutable sc_event_finder* m_neg_finder_p;
01390   mutable sc_event_finder* m_pos_finder_p;
01391 
01392 private:
01393 
01394     // disabled
01395     sc_inout( const this_type& );
01396 
01397 #ifdef __GNUC__
01398     // Needed to circumvent a problem in the g++-2.95.2 compiler:
01399     // This unused variable forces the compiler to instantiate
01400     // an object of T template so an implicit conversion from
01401     // read() to a C++ intrinsic data type will work.
01402     static data_type dummy;
01403 #endif
01404 };
01405 
01406 
01407 // ----------------------------------------------------------------------------
01408 //  CLASS : sc_inout<sc_dt::sc_logic>
01409 //
01410 //  Specialization of sc_inout<T> for type sc_dt::sc_logic.
01411 // ----------------------------------------------------------------------------
01412 
01413 template <>
01414 class sc_inout<sc_dt::sc_logic>
01415 : public sc_port<sc_signal_inout_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
01416 {
01417 public:
01418 
01419     // typedefs
01420 
01421     typedef sc_dt::sc_logic                            data_type;
01422 
01423     typedef sc_signal_inout_if<data_type>              if_type;
01424     typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>    base_type;
01425     typedef sc_inout<data_type>                        this_type;
01426 
01427     typedef sc_signal_in_if<data_type>                 in_if_type;
01428     typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
01429     typedef if_type                                    inout_if_type;
01430     typedef base_type                                  inout_port_type;
01431 
01432 public:
01433 
01434     // constructors
01435 
01436     sc_inout()
01437     : base_type(), m_init_val( 0 ), m_traces( 0 ),
01438       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01439     {}
01440 
01441     explicit sc_inout( const char* name_ )
01442     : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
01443       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01444     {}
01445 
01446     explicit sc_inout( inout_if_type& interface_ )
01447     : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
01448       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01449     {}
01450 
01451     sc_inout( const char* name_, inout_if_type& interface_ )
01452     : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
01453       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01454     {}
01455 
01456     explicit sc_inout( inout_port_type& parent_ )
01457     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01458       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01459     {}
01460 
01461     sc_inout( const char* name_, inout_port_type& parent_ )
01462     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01463       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01464     {}
01465 
01466     sc_inout( this_type& parent_ )
01467     : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
01468       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01469     {}
01470 
01471     sc_inout( const char* name_, this_type& parent_ )
01472     : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
01473       m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
01474     {}
01475 
01476 
01477     // destructor
01478 
01479     virtual ~sc_inout();
01480 
01481 
01482     // interface access shortcut methods
01483 
01484     // get the default event
01485 
01486     const sc_event& default_event() const
01487     { return (*this)->default_event(); }
01488 
01489 
01490     // get the value changed event
01491 
01492     const sc_event& value_changed_event() const
01493     { return (*this)->value_changed_event(); }
01494 
01495     // get the positive edge event
01496 
01497     const sc_event& posedge_event() const
01498     { return (*this)->posedge_event(); }
01499 
01500     // get the negative edge event
01501 
01502     const sc_event& negedge_event() const
01503     { return (*this)->negedge_event(); }
01504 
01505 
01506     // read the current value
01507 
01508     const data_type& read() const
01509     { return (*this)->read(); }
01510 
01511     operator const data_type& () const
01512     { return (*this)->read(); }
01513 
01514 
01515     // use for positive edge sensitivity
01516 
01517     sc_event_finder& pos() const
01518     {
01519         if ( !m_pos_finder_p )
01520     {
01521         m_pos_finder_p = new sc_event_finder_t<in_if_type>(
01522             *this, &in_if_type::posedge_event );
01523     } 
01524     return *m_pos_finder_p;
01525     }
01526 
01527     // use for negative edge sensitivity
01528 
01529     sc_event_finder& neg() const
01530     {
01531         if ( !m_neg_finder_p )
01532     {
01533         m_neg_finder_p = new sc_event_finder_t<in_if_type>(
01534             *this, &in_if_type::negedge_event );
01535     } 
01536     return *m_neg_finder_p;
01537     }
01538 
01539 
01540     // was there a value changed event?
01541 
01542     bool event() const
01543     { return (*this)->event(); }
01544 
01545     // was there a positive edge event?
01546 
01547     bool posedge() const
01548         { return (*this)->posedge(); }
01549 
01550     // was there a negative edge event?
01551 
01552     bool negedge() const
01553         { return (*this)->negedge(); }
01554 
01555     // write the new value
01556 
01557     void write( const data_type& value_ )
01558     { (*this)->write( value_ ); }
01559 
01560     this_type& operator = ( const data_type& value_ )
01561     { (*this)->write( value_ ); return *this; }
01562 
01563     this_type& operator = ( const in_if_type& interface_ )
01564     { (*this)->write( interface_.read() ); return *this; }
01565 
01566     this_type& operator = ( const in_port_type& port_ )
01567     { (*this)->write( port_->read() ); return *this; }
01568 
01569     this_type& operator = ( const inout_port_type& port_ )
01570     { (*this)->write( port_->read() ); return *this; }
01571 
01572     this_type& operator = ( const this_type& port_ )
01573     { (*this)->write( port_->read() ); return *this; }
01574 
01575 
01576     // set initial value (can also be called when port is not bound yet)
01577 
01578     void initialize( const data_type& value_ );
01579 
01580     void initialize( const in_if_type& interface_ )
01581     { initialize( interface_.read() ); }
01582 
01583 
01584     // called when elaboration is done
01585     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
01586     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
01587 
01588     virtual void end_of_elaboration();
01589 
01590 
01591     // (other) event finder method(s)
01592 
01593     sc_event_finder& value_changed() const
01594     {
01595         if ( !m_change_finder_p )
01596     {
01597         m_change_finder_p = new sc_event_finder_t<in_if_type>(
01598             *this, &in_if_type::value_changed_event );
01599     }
01600         return *m_change_finder_p;
01601     }
01602 
01603     virtual const char* kind() const
01604         { return "sc_inout"; }
01605 
01606 protected:
01607 
01608     data_type* m_init_val;
01609 
01610 public:
01611 
01612     // called by sc_trace
01613     void add_trace_internal( sc_trace_file*, const std::string& ) const;
01614 
01615     void add_trace( sc_trace_file*, const std::string& ) const;
01616 
01617 protected:
01618 
01619     void remove_traces() const;
01620 
01621     mutable sc_trace_params_vec* m_traces;
01622 
01623 private:
01624   mutable sc_event_finder* m_change_finder_p;
01625   mutable sc_event_finder* m_neg_finder_p;
01626   mutable sc_event_finder* m_pos_finder_p;
01627 
01628 private:
01629 
01630     // disabled
01631     sc_inout( const this_type& );
01632 
01633 #ifdef __GNUC__
01634     // Needed to circumvent a problem in the g++-2.95.2 compiler:
01635     // This unused variable forces the compiler to instantiate
01636     // an object of T template so an implicit conversion from
01637     // read() to a C++ intrinsic data type will work.
01638     static data_type dummy;
01639 #endif
01640 };
01641 
01642 
01643 // ----------------------------------------------------------------------------
01644 //  CLASS : sc_out<T>
01645 //
01646 //  The sc_signal<T> output port class.
01647 // ----------------------------------------------------------------------------
01648 
01649 // sc_out can also read from its port, hence no difference with sc_inout.
01650 // For debugging reasons, a class is provided instead of a define.
01651 
01652 template <class T>
01653 class sc_out
01654 : public sc_inout<T>
01655 {
01656 public:
01657 
01658     // typedefs
01659 
01660     typedef T                                   data_type;
01661 
01662     typedef sc_out<data_type>                   this_type;
01663     typedef sc_inout<data_type>                 base_type;
01664 
01665     typedef typename base_type::in_if_type      in_if_type;
01666     typedef typename base_type::in_port_type    in_port_type;
01667     typedef typename base_type::inout_if_type   inout_if_type;
01668     typedef typename base_type::inout_port_type inout_port_type;
01669 
01670 public:
01671 
01672     // constructors
01673 
01674     sc_out()
01675     : base_type()
01676     {}
01677 
01678     explicit sc_out( const char* name_ )
01679     : base_type( name_ )
01680     {}
01681 
01682     explicit sc_out( inout_if_type& interface_ )
01683     : base_type( interface_ )
01684     {}
01685 
01686     sc_out( const char* name_, inout_if_type& interface_ )
01687     : base_type( name_, interface_ )
01688     {}
01689 
01690     explicit sc_out( inout_port_type& parent_ )
01691     : base_type( parent_ )
01692     {}
01693 
01694     sc_out( const char* name_, inout_port_type& parent_ )
01695     : base_type( name_, parent_ )
01696     {}
01697 
01698     sc_out( this_type& parent_ )
01699     : base_type( parent_ )
01700     {}
01701 
01702     sc_out( const char* name_, this_type& parent_ )
01703     : base_type( name_, parent_ )
01704     {}
01705 
01706 
01707     // destructor (does nothing)
01708 
01709     virtual ~sc_out()
01710     {}
01711 
01712 
01713     // write the new value
01714 
01715     this_type& operator = ( const data_type& value_ )
01716     { (*this)->write( value_ ); return *this; }
01717 
01718     this_type& operator = ( const in_if_type& interface_ )
01719     { (*this)->write( interface_.read() ); return *this; }
01720 
01721     this_type& operator = ( const in_port_type& port_ )
01722     { (*this)->write( port_->read() ); return *this; }
01723 
01724     this_type& operator = ( const inout_port_type& port_ )
01725     { (*this)->write( port_->read() ); return *this; }
01726 
01727     this_type& operator = ( const this_type& port_ )
01728     { (*this)->write( port_->read() ); return *this; }
01729 
01730     virtual const char* kind() const
01731         { return "sc_out"; }
01732 
01733 private:
01734 
01735     // disabled
01736     sc_out( const this_type& );
01737 };
01738 
01739 
01740 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01741 
01742 
01743 // ----------------------------------------------------------------------------
01744 //  FUNCTION : sc_trace
01745 // ----------------------------------------------------------------------------
01746 
01747 template <class T>
01748 inline
01749 void
01750 sc_trace(sc_trace_file* tf, const sc_in<T>& port, const std::string& name)
01751 {
01752     const sc_signal_in_if<T>* iface = 0;
01753     if (sc_get_curr_simcontext()->elaboration_done() )
01754     {
01755     iface = DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
01756     }
01757 
01758     if ( iface )
01759     sc_trace( tf, iface->read(), name );
01760     else
01761     port.add_trace_internal( tf, name );
01762 }
01763 
01764 template <class T>
01765 inline
01766 void
01767 sc_trace( sc_trace_file* tf, const sc_inout<T>& port, 
01768     const std::string& name )
01769 {
01770     const sc_signal_in_if<T>* iface = 0;
01771     if (sc_get_curr_simcontext()->elaboration_done() )
01772     {
01773     iface =DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
01774     }
01775 
01776     if ( iface )
01777     sc_trace( tf, iface->read(), name );
01778     else
01779     port.add_trace_internal( tf, name );
01780 }
01781 
01782 } // namespace sc_core
01783 
01784 /*****************************************************************************
01785 
01786   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
01787   changes you are making here.
01788 
01789       Name, Affiliation, Date:  Jason Elbaum, Motorola, Inc., 2001-11-12
01790   Description of Modification:  Added a static, private, otherwise
01791                                 unused data member to the sc_in
01792                                 and sc_inout classes to address
01793                                 a bug in the GNU compiler *only*.
01794                                 This works around a bug in g++ 2.95.2
01795                                 regarding implicit casting from a
01796                                 templated class to a C++ intrinsic type.
01797 
01798  *****************************************************************************/
01799 //$Log: sc_signal_ports.h,v $
01800 //Revision 1.1.1.1  2006/12/15 20:31:35  acg
01801 //SystemC 2.2
01802 //
01803 //Revision 1.11  2006/04/18 23:36:50  acg
01804 // Andy Goodrich: made add_trace_internal public until I can figure out
01805 // how to do a friend specification for sc_trace in an environment where
01806 // there are partial template and full template specifications for its
01807 // arguments.
01808 //
01809 //Revision 1.10  2006/04/18 18:01:26  acg
01810 // Andy Goodrich: added an add_trace_internal() method to the various port
01811 // classes so that sc_trace has something to call that won't emit an
01812 // IEEE 1666 deprecation message.
01813 //
01814 //Revision 1.9  2006/03/13 20:19:44  acg
01815 // Andy Goodrich: changed sc_event instances into pointers to sc_event instances
01816 // that are allocated as needed. This saves considerable storage for large
01817 // numbers of signals, etc.
01818 //
01819 //Revision 1.8  2006/02/02 23:42:37  acg
01820 // Andy Goodrich: implemented a much better fix to the sc_event_finder
01821 // proliferation problem. This new version allocates only a single event
01822 // finder for each port for each type of event, e.g., pos(), neg(), and
01823 // value_change(). The event finder persists as long as the port does,
01824 // which is what the LRM dictates. Because only a single instance is
01825 // allocated for each event type per port there is not a potential
01826 // explosion of storage as was true in the 2.0.1/2.1 versions.
01827 //
01828 //Revision 1.7  2006/02/02 21:38:12  acg
01829 // Andy Goodrich: fix to the comment log.
01830 //
01831 //Revision 1.4  2006/01/24 20:46:32  acg
01832 //Andy Goodrich: changes to eliminate use of deprecated features. For instance,
01833 //using notify(SC_ZERO_TIME) in place of notify_delayed().
01834 //
01835 //Revision 1.3  2006/01/13 18:47:42  acg
01836 //Added $Log command so that CVS comments are reproduced in the source.
01837 //
01838 //Revision 1.2  2006/01/03 23:18:26  acg
01839 //Changed copyright to include 2006.
01840 //
01841 //Revision 1.1.1.1  2005/12/19 23:16:43  acg
01842 //First check in of SystemC 2.1 into its own archive.
01843 //
01844 //Revision 1.18  2005/09/15 23:01:52  acg
01845 //Added std:: prefix to appropriate methods and types to get around
01846 //issues with the Edison Front End.
01847 //
01848 //Revision 1.17  2005/06/10 22:43:55  acg
01849 //Added CVS change log annotation.
01850 //
01851 
01852 #endif
01853 
01854 // Taf!

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