sc_event.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_event.h --
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
00033 
00034  *****************************************************************************/
00035 
00036 // $Log: sc_event.h,v $
00037 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00038 // SystemC 2.2
00039 //
00040 // Revision 1.6  2006/04/11 23:13:20  acg
00041 //   Andy Goodrich: Changes for reduced reset support that only includes
00042 //   sc_cthread, but has preliminary hooks for expanding to method and thread
00043 //   processes also.
00044 //
00045 // Revision 1.5  2006/01/24 20:56:00  acg
00046 //  Andy Goodrich: fixed up CVS comment.
00047 //
00048 // Revision 1.4  2006/01/24 20:48:14  acg
00049 // Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
00050 // new implementation-dependent methods, notify_next_delta() & notify_internal()
00051 // to replace calls to notify_delayed() from within the simulator. These two
00052 // new methods are simpler than notify_delayed() and should speed up simulations
00053 //
00054 // Revision 1.3  2006/01/13 18:44:29  acg
00055 // Added $Log to record CVS changes into the source.
00056 //
00057 
00058 #ifndef SC_EVENT_H
00059 #define SC_EVENT_H
00060 
00061 
00062 #include "sysc/kernel/sc_kernel_ids.h"
00063 #include "sysc/kernel/sc_simcontext.h"
00064 #include "sysc/datatypes/bit/sc_logic.h"
00065 
00066 namespace sc_core {
00067 
00068 // forward declarations
00069 class sc_event_timed;
00070 class sc_event_list;
00071 class sc_event_or_list;
00072 class sc_event_and_list;
00073 
00074 // friend function declarations
00075     int sc_notify_time_compare( const void*, const void* );
00076 
00077 
00078 
00079 // ----------------------------------------------------------------------------
00080 //  CLASS : sc_event
00081 //
00082 //  The event class.
00083 // ----------------------------------------------------------------------------
00084 
00085 class sc_event
00086 {
00087     friend class sc_clock;
00088     friend class sc_event_list;
00089     friend class sc_event_timed;
00090     friend class sc_simcontext;
00091     friend class sc_process_b;
00092     friend class sc_method_process;
00093     friend class sc_thread_process;
00094     template<typename IF> friend class sc_signal;
00095     friend class sc_signal<bool>;
00096     friend class sc_signal<sc_dt::sc_logic>;
00097 
00098 public:
00099 
00100     sc_event();
00101     ~sc_event();
00102 
00103     void cancel();
00104 
00105 
00106     void notify();
00107     void notify( const sc_time& );
00108     void notify( double, sc_time_unit );
00109 
00110     void notify_delayed();
00111     void notify_delayed( const sc_time& );
00112     void notify_delayed( double, sc_time_unit );
00113 
00114     sc_event_or_list&  operator | ( const sc_event& ) const;
00115     sc_event_and_list& operator & ( const sc_event& ) const;
00116 
00117 
00118 private:
00119 
00120     void add_static( sc_method_handle ) const;
00121     void add_static( sc_thread_handle ) const;
00122     void add_dynamic( sc_method_handle ) const;
00123     void add_dynamic( sc_thread_handle ) const;
00124 
00125     void notify_internal( const sc_time& );
00126     void notify_next_delta();
00127 
00128     bool remove_static( sc_method_handle ) const;
00129     bool remove_static( sc_thread_handle ) const;
00130     bool remove_dynamic( sc_method_handle ) const;
00131     bool remove_dynamic( sc_thread_handle ) const;
00132 
00133     void reset();
00134 
00135     void trigger();
00136 
00137 private:
00138 
00139     enum notify_t { NONE, DELTA, TIMED };
00140 
00141     sc_simcontext*  m_simc;
00142     notify_t        m_notify_type;
00143     int             m_delta_event_index;
00144     sc_event_timed* m_timed;
00145 
00146     mutable std::vector<sc_method_handle> m_methods_static;
00147     mutable std::vector<sc_method_handle> m_methods_dynamic;
00148     mutable std::vector<sc_thread_handle> m_threads_static;
00149     mutable std::vector<sc_thread_handle> m_threads_dynamic;
00150 
00151 private:
00152 
00153     // disabled
00154     sc_event( const sc_event& );
00155     sc_event& operator = ( const sc_event& );
00156 };
00157 
00158 extern sc_event sc_non_event; // Event that never happens.
00159 
00160 // ----------------------------------------------------------------------------
00161 //  CLASS : sc_event_timed
00162 //
00163 //  Class for storing the time to notify a timed event.
00164 // ----------------------------------------------------------------------------
00165 
00166 class sc_event_timed
00167 {
00168     friend class sc_event;
00169     friend class sc_simcontext;
00170 
00171     friend int sc_notify_time_compare( const void*, const void* );
00172 
00173 private:
00174 
00175     sc_event_timed( sc_event* e, const sc_time& t )
00176         : m_event( e ), m_notify_time( t )
00177         {}
00178 
00179     ~sc_event_timed()
00180         { if( m_event != 0 ) { m_event->m_timed = 0; } }
00181 
00182     sc_event* event() const
00183         { return m_event; }
00184 
00185     const sc_time& notify_time() const
00186         { return m_notify_time; }
00187 
00188     static void* operator new( std::size_t )
00189         { return allocate(); }
00190 
00191     static void operator delete( void* p, std::size_t )
00192         { deallocate( p ); }
00193 
00194 private:
00195 
00196     // dedicated memory management
00197     static void* allocate();
00198     static void  deallocate( void* );
00199 
00200 private:
00201 
00202     sc_event* m_event;
00203     sc_time   m_notify_time;
00204 
00205 private:
00206 
00207     // disabled
00208     sc_event_timed();
00209     sc_event_timed( const sc_event_timed& );
00210     sc_event_timed& operator = ( const sc_event_timed& );
00211 };
00212 
00213 
00214 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00215 
00216 inline
00217 sc_event::sc_event()
00218 : m_simc( sc_get_curr_simcontext() ),
00219   m_notify_type( NONE ),
00220   m_delta_event_index( -1 ),
00221   m_timed( 0 )
00222 {}
00223 
00224 inline
00225 sc_event::~sc_event()
00226 {
00227     cancel();
00228 }
00229 
00230 inline
00231 void
00232 sc_event::notify( double v, sc_time_unit tu )
00233 {
00234     notify( sc_time( v, tu, m_simc ) );
00235 }
00236 
00237 
00238 inline
00239 void
00240 sc_event::notify_internal( const sc_time& t )
00241 {
00242     if( t == SC_ZERO_TIME ) {
00243         // add this event to the delta events set
00244         m_delta_event_index = m_simc->add_delta_event( this );
00245         m_notify_type = DELTA;
00246     } else {
00247         sc_event_timed* et =
00248         new sc_event_timed( this, m_simc->time_stamp() + t );
00249         m_simc->add_timed_event( et );
00250         m_timed = et;
00251         m_notify_type = TIMED;
00252     }
00253 }
00254 
00255 inline
00256 void
00257 sc_event::notify_next_delta()
00258 {
00259     if( m_notify_type != NONE ) {
00260         SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00261     }
00262     // add this event to the delta events set
00263     m_delta_event_index = m_simc->add_delta_event( this );
00264     m_notify_type = DELTA;
00265 }
00266 
00267 inline
00268 void
00269 sc_event::notify_delayed( double v, sc_time_unit tu )
00270 {
00271     notify_delayed( sc_time( v, tu, m_simc ) );
00272 }
00273 
00274 
00275 inline
00276 void
00277 sc_event::add_static( sc_method_handle method_h ) const
00278 {
00279     m_methods_static.push_back( method_h );
00280 }
00281 
00282 inline
00283 void
00284 sc_event::add_static( sc_thread_handle thread_h ) const
00285 {
00286     m_threads_static.push_back( thread_h );
00287 }
00288 
00289 inline
00290 void
00291 sc_event::add_dynamic( sc_method_handle method_h ) const
00292 {
00293     m_methods_dynamic.push_back( method_h );
00294 }
00295 
00296 inline
00297 void
00298 sc_event::add_dynamic( sc_thread_handle thread_h ) const
00299 {
00300     m_threads_dynamic.push_back( thread_h );
00301 }
00302 
00303 
00304 // ----------------------------------------------------------------------------
00305 //  Deprecated functional notation for notifying events.
00306 // ----------------------------------------------------------------------------
00307 
00308 extern void notify( sc_event& e );
00309 extern void notify( const sc_time& t, sc_event& e );
00310 extern void notify( double v, sc_time_unit tu, sc_event& e );
00311 
00312 
00313 // ----------------------------------------------------------------------------
00314 //  CLASS : sc_event_list
00315 //
00316 //  Base class for lists of events.
00317 // ----------------------------------------------------------------------------
00318 
00319 class sc_event_list
00320 {
00321     friend class sc_process_b;
00322     friend class sc_method_process;
00323     friend class sc_thread_process;
00324 
00325 protected:
00326 
00327     void push_back( const sc_event& );
00328 
00329     sc_event_list( const sc_event&,
00330                    bool and_list_,
00331                    bool auto_delete_ = false );
00332 
00333     int size() const;
00334     bool and_list() const;
00335 
00336     void add_dynamic( sc_method_handle );
00337     void add_dynamic( sc_thread_handle );
00338     void remove_dynamic( sc_method_handle, const sc_event* );
00339     void remove_dynamic( sc_thread_handle, const sc_event* );
00340 
00341     void auto_delete();
00342 
00343 private:
00344 
00345     std::vector<const sc_event*> m_events;
00346     bool                         m_and_list;
00347     bool                         m_auto_delete;
00348 
00349 private:
00350 
00351     // disabled
00352     sc_event_list();
00353     sc_event_list( const sc_event_list& );
00354     sc_event_list& operator = ( const sc_event_list& );
00355 };
00356 
00357 
00358 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00359 
00360 inline
00361 sc_event_list::sc_event_list( const sc_event& e,
00362                               bool and_list_,
00363                               bool auto_delete_ )
00364 : m_and_list( and_list_ ),
00365   m_auto_delete( auto_delete_ )
00366 {
00367     m_events.push_back( &e );
00368 }
00369 
00370 
00371 inline
00372 int
00373 sc_event_list::size() const
00374 {
00375     return m_events.size();
00376 }
00377 
00378 inline
00379 bool
00380 sc_event_list::and_list() const
00381 {
00382     return m_and_list;
00383 }
00384 
00385 
00386 inline
00387 void
00388 sc_event_list::auto_delete()
00389 {
00390     if( m_auto_delete ) {
00391         delete this;
00392     }
00393 }
00394 
00395 
00396 // ----------------------------------------------------------------------------
00397 //  CLASS : sc_event_or_list
00398 //
00399 //  OR list of events.
00400 // ----------------------------------------------------------------------------
00401 
00402 class sc_event_or_list
00403 : public sc_event_list
00404 {
00405     friend class sc_event;
00406     friend class sc_process_b;
00407     friend class sc_method_process;
00408     friend class sc_thread_process;
00409 
00410 protected:
00411 
00412     sc_event_or_list( const sc_event&, bool auto_delete_ = false );
00413 
00414 public:
00415 
00416     sc_event_or_list& operator | ( const sc_event& );
00417 
00418 private:
00419 
00420     // disabled
00421     sc_event_or_list();
00422     sc_event_or_list( const sc_event_or_list& );
00423     sc_event_or_list& operator = ( const sc_event_or_list& );
00424 };
00425 
00426 
00427 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00428 
00429 inline
00430 sc_event_or_list::sc_event_or_list( const sc_event& e,
00431                                     bool auto_delete_ )
00432 : sc_event_list( e, false, auto_delete_ )
00433 {}
00434 
00435 
00436 inline
00437 sc_event_or_list&
00438 sc_event_or_list::operator | ( const sc_event& e )
00439 {
00440     push_back( e );
00441     return *this;
00442 }
00443 
00444 
00445 // sc_event
00446 
00447 inline
00448 sc_event_or_list&
00449 sc_event::operator | ( const sc_event& e2 ) const
00450 {
00451     sc_event_or_list* el = new sc_event_or_list( *this, true );
00452     el->push_back( e2 );
00453     return *el;
00454 }
00455 
00456 
00457 // ----------------------------------------------------------------------------
00458 //  CLASS : sc_event_and_list
00459 //
00460 //  AND list of events.
00461 // ----------------------------------------------------------------------------
00462 
00463 class sc_event_and_list
00464 : public sc_event_list
00465 {
00466     friend class sc_event;
00467     friend class sc_process_b;
00468     friend class sc_method_process;
00469     friend class sc_thread_process;
00470 
00471 protected:
00472 
00473     sc_event_and_list( const sc_event&, bool auto_delete_ = false );
00474 
00475 public:
00476 
00477     sc_event_and_list& operator & ( const sc_event& );
00478 
00479 private:
00480 
00481     // disabled
00482     sc_event_and_list();
00483     sc_event_and_list( const sc_event_and_list& );
00484     sc_event_and_list& operator = ( const sc_event_and_list& );
00485 };
00486 
00487 
00488 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00489 
00490 inline
00491 sc_event_and_list::sc_event_and_list( const sc_event& e,
00492                                       bool auto_delete_ )
00493 : sc_event_list( e, true, auto_delete_ )
00494 {}
00495 
00496 
00497 inline
00498 sc_event_and_list&
00499 sc_event_and_list::operator & ( const sc_event& e )
00500 {
00501     push_back( e );
00502     return *this;
00503 }
00504 
00505 
00506 // sc_event
00507 
00508 inline
00509 sc_event_and_list&
00510 sc_event::operator & ( const sc_event& e2 ) const
00511 {
00512     sc_event_and_list* el = new sc_event_and_list( *this, true );
00513     el->push_back( e2 );
00514     return *el;
00515 }
00516 
00517 } // namespace sc_core
00518 
00519 #endif
00520 
00521 // Taf!

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