00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #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
00069 class sc_event_timed;
00070 class sc_event_list;
00071 class sc_event_or_list;
00072 class sc_event_and_list;
00073
00074
00075 int sc_notify_time_compare( const void*, const void* );
00076
00077
00078
00079
00080
00081
00082
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
00154 sc_event( const sc_event& );
00155 sc_event& operator = ( const sc_event& );
00156 };
00157
00158 extern sc_event sc_non_event;
00159
00160
00161
00162
00163
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
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
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
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
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
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
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
00315
00316
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
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
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
00398
00399
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
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
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
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
00459
00460
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
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
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
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 }
00518
00519 #endif
00520
00521