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 #ifndef SC_EVENT_H
00029 #define SC_EVENT_H
00030
00031 #include "sysc/kernel/sc_cmnhdr.h"
00032 #include "sysc/kernel/sc_kernel_ids.h"
00033 #include "sysc/kernel/sc_simcontext.h"
00034 #include "sysc/communication/sc_writer_policy.h"
00035
00036 #ifndef _SYSC_PRINT_VERBOSE_MESSAGE_ENV_VAR
00037 #define _SYSC_PRINT_VERBOSE_MESSAGE_ENV_VAR "SYSC_PRINT_VERBOSE_MESSAGE"
00038 #endif
00039 namespace sc_core {
00040
00041
00042 class sc_event;
00043 class sc_event_timed;
00044 class sc_event_list;
00045 class sc_event_or_list;
00046 class sc_event_and_list;
00047 class sc_object;
00048
00049
00050 int sc_notify_time_compare( const void*, const void* );
00051
00052
00058 template< typename T >
00059 class sc_event_expr
00060 {
00061 friend class sc_event;
00062 friend class sc_event_and_list;
00063 friend class sc_event_or_list;
00064
00065 typedef T type;
00066
00067 inline sc_event_expr()
00068 : m_expr( new T(true) )
00069 {}
00070
00071 public:
00072
00073 inline sc_event_expr( sc_event_expr const & e)
00074 : m_expr(e.m_expr)
00075 {
00076 e.m_expr = 0;
00077 }
00078
00079 T const & release() const
00080 {
00081 sc_assert( m_expr );
00082 T* expr = m_expr;
00083 m_expr=0;
00084 return *expr;
00085 }
00086
00087 void push_back( sc_event const & e) const
00088 {
00089 sc_assert( m_expr );
00090 m_expr->push_back(e);
00091 }
00092
00093 void push_back( type const & el) const
00094 {
00095 sc_assert( m_expr );
00096 m_expr->push_back(el);
00097 }
00098 operator T const &() const
00099 {
00100 return release();
00101 }
00102
00103 ~sc_event_expr()
00104 {
00105 delete m_expr;
00106 }
00107
00108 private:
00109 mutable type * m_expr;
00110
00111
00112 void operator=( sc_event_expr const & );
00113 };
00114
00115
00121 class sc_event_list
00122 {
00123 friend class sc_process_b;
00124 friend class sc_method_process;
00125 friend class sc_thread_process;
00126 friend void sc_thread_cor_fn( void* arg );
00127
00128 public:
00129 sc_event_list( const sc_event_list& );
00130 sc_event_list& operator = ( const sc_event_list& );
00131
00132 int size() const;
00133
00134 protected:
00135
00136 void push_back( const sc_event& );
00137 void push_back( const sc_event_list& );
00138
00139 explicit
00140 sc_event_list( bool and_list_, bool auto_delete_ = false );
00141
00142 sc_event_list( const sc_event&,
00143 bool and_list_,
00144 bool auto_delete_ = false );
00145
00146 ~sc_event_list();
00147
00148 void swap( sc_event_list& );
00149 void move_from( const sc_event_list& );
00150
00151 bool and_list() const;
00152
00153 void add_dynamic( sc_method_handle ) const;
00154 void add_dynamic( sc_thread_handle ) const;
00155 void remove_dynamic( sc_method_handle, const sc_event* ) const;
00156 void remove_dynamic( sc_thread_handle, const sc_event* ) const;
00157
00158 bool busy() const;
00159 bool temporary() const;
00160 void auto_delete() const;
00161
00162 void report_premature_destruction() const;
00163 void report_invalid_modification() const;
00164
00165 private:
00166
00167 std::vector<const sc_event*> m_events;
00168 bool m_and_list;
00169 bool m_auto_delete;
00170 mutable unsigned m_busy;
00171 };
00172
00173
00174
00180 class sc_event_and_list
00181 : public sc_event_list
00182 {
00183 friend class sc_event;
00184 friend class sc_event_expr<sc_event_and_list>;
00185 friend class sc_process_b;
00186 friend class sc_method_process;
00187 friend class sc_thread_process;
00188
00189 protected:
00190
00191 explicit
00192 sc_event_and_list( bool auto_delete_ );
00193
00194 public:
00195
00196 sc_event_and_list();
00197 sc_event_and_list( const sc_event& );
00198
00199 void swap( sc_event_and_list& );
00200 sc_event_and_list& operator &= ( const sc_event& );
00201 sc_event_and_list& operator &= ( const sc_event_and_list & );
00202
00203 sc_event_expr<sc_event_and_list> operator & ( const sc_event& );
00204 sc_event_expr<sc_event_and_list> operator & ( const sc_event_and_list& );
00205 };
00206
00207 typedef sc_event_expr<sc_event_and_list> sc_event_and_expr;
00208
00209
00215 class sc_event_or_list
00216 : public sc_event_list
00217 {
00218 friend class sc_event;
00219 friend class sc_event_expr<sc_event_or_list>;
00220 friend class sc_process_b;
00221 friend class sc_method_process;
00222 friend class sc_thread_process;
00223
00224 protected:
00225
00226 explicit
00227 sc_event_or_list( bool auto_delete_ );
00228
00229 public:
00230 sc_event_or_list();
00231 sc_event_or_list( const sc_event& );
00232 void swap( sc_event_or_list& );
00233 sc_event_or_list& operator |= ( const sc_event& );
00234 sc_event_or_list& operator |= ( const sc_event_or_list & );
00235 sc_event_expr<sc_event_or_list> operator | ( const sc_event& ) const;
00236 sc_event_expr<sc_event_or_list> operator | ( const sc_event_or_list& ) const;
00237 };
00238
00239 typedef sc_event_expr<sc_event_or_list> sc_event_or_expr;
00240
00241
00247 class sc_event
00248 {
00249 friend class sc_clock;
00250 friend class sc_event_list;
00251 friend class sc_event_timed;
00252 friend class sc_simcontext;
00253 friend class sc_object;
00254 friend class sc_process_b;
00255 friend class sc_method_process;
00256 friend class sc_thread_process;
00257 template<typename IF, sc_writer_policy POL> friend class sc_signal;
00258 friend void sc_thread_cor_fn( void* arg );
00259
00260 public:
00261
00262 std::vector<sc_timestamp> m_notify_timestamp_list;
00263 sc_event();
00264 sc_event( const char* name );
00265 ~sc_event();
00266
00267 void cancel();
00268
00269 const char* name() const { return m_name.c_str(); }
00270 const char* basename() const;
00271 sc_object* get_parent_object() const { return m_parent_p; }
00272 bool in_hierarchy() const { return m_name.length() != 0; }
00273
00278
00279 void notify();
00280
00281 void notify( const sc_time& );
00282 void notify( double, sc_time_unit );
00283
00284 void notify_delayed();
00285 void notify_delayed( const sc_time& );
00286 void notify_delayed( double, sc_time_unit );
00287
00288 sc_event_or_expr operator | ( const sc_event& ) const;
00289 sc_event_or_expr operator | ( const sc_event_or_list& ) const;
00290 sc_event_and_expr operator & ( const sc_event& ) const;
00291 sc_event_and_expr operator & ( const sc_event_and_list& ) const;
00292
00296
00297 const sc_timestamp& get_notify_timestamp() const;
00298 void push_notify_timestamp_list( const sc_timestamp& ts );
00299 const sc_timestamp& get_notify_timestamp_last() const;
00300 mutable std::vector<sc_method_handle> m_methods_static;
00301 mutable std::vector<sc_method_handle> m_methods_dynamic;
00302 mutable std::vector<sc_thread_handle> m_threads_static;
00303 mutable std::vector<sc_thread_handle> m_threads_dynamic;
00304 private:
00305
00306 void add_static( sc_method_handle ) const;
00307 void add_static( sc_thread_handle ) const;
00308 void add_dynamic( sc_method_handle ) const;
00309 void add_dynamic( sc_thread_handle ) const;
00310
00311 void notify_internal( const sc_time& );
00312 void notify_next_delta();
00313
00314 bool remove_static( sc_method_handle ) const;
00315 bool remove_static( sc_thread_handle ) const;
00316 bool remove_dynamic( sc_method_handle ) const;
00317 bool remove_dynamic( sc_thread_handle ) const;
00318
00319 void register_event( const char* name );
00320 void reset();
00321
00322 void trigger();
00323
00324
00328
00329 void set_notify_timestamp( const sc_timestamp& ts );
00330
00331 private:
00332
00333 enum notify_t { NONE, DELTA, TIMED };
00334
00335 std::string m_name;
00336 sc_object* m_parent_p;
00337 sc_simcontext* m_simc;
00338
00339
00340 sc_event_timed* m_timed;
00341
00342
00343
00344
00348
00349 sc_timestamp m_notify_timestamp;
00350
00351 private:
00352
00353
00354 sc_event( const sc_event& );
00355 sc_event& operator = ( const sc_event& );
00356 notify_t m_notify_type;
00357
00358 public:
00359 int m_delta_event_index;
00360 };
00361
00362 #define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
00363
00364 extern sc_event sc_non_event;
00365
00366
00372 class sc_event_timed
00373 {
00374 friend class sc_event;
00375 friend class sc_simcontext;
00376
00377 friend int sc_notify_time_compare( const void*, const void* );
00378
00379 private:
00380
00381 sc_event_timed( sc_event* e, const sc_time& t )
00382 : m_event( e ), m_notify_time( t )
00383 {}
00384
00385 ~sc_event_timed()
00386 { if( m_event != 0 ) { m_event->m_timed = 0; } }
00387
00388 sc_event* event() const
00389 { return m_event; }
00390
00391 const sc_time& notify_time() const
00392 { return m_notify_time; }
00393
00394 static void* operator new( std::size_t )
00395 { return allocate(); }
00396
00397 static void operator delete( void* p, std::size_t )
00398 { deallocate( p ); }
00399
00400 private:
00401
00402
00403 static void* allocate();
00404 static void deallocate( void* );
00405
00406 private:
00407
00408 sc_event* m_event;
00409 sc_time m_notify_time;
00410
00411 private:
00412
00413
00414 sc_event_timed();
00415 sc_event_timed( const sc_event_timed& );
00416 sc_event_timed& operator = ( const sc_event_timed& );
00417 };
00418
00419
00420
00421
00422 inline
00423 void
00424 sc_event::notify( double v, sc_time_unit tu )
00425 {
00426 notify( sc_time( v, tu, m_simc ) );
00427 }
00428
00429
00430 inline
00431 void
00432 sc_event::notify_internal( const sc_time& t )
00433 {
00434
00435 sc_process_b* m_proc = m_simc->get_curr_proc();
00436
00437 if( t == SC_ZERO_TIME ) {
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 sc_event_timed* et = new sc_event_timed( this,
00449 m_proc->get_timestamp().get_time_count() + t );
00450 m_simc->add_timed_event( et );
00451 m_timed = et;
00452 m_notify_type = TIMED;
00453
00454
00455 set_notify_timestamp( sc_timestamp( m_proc->get_timestamp().
00456 get_time_count() , m_proc->get_timestamp().
00457 get_delta_count() +1 ) );
00458 } else {
00459
00460
00461
00462
00463 sc_event_timed* et = new sc_event_timed( this,
00464 m_proc->get_timestamp().get_time_count() + t );
00465 m_simc->add_timed_event( et );
00466 m_timed = et;
00467 m_notify_type = TIMED;
00468
00469
00470 set_notify_timestamp( sc_timestamp( m_proc->get_timestamp().
00471 get_time_count() + t, 0 ) );
00472 }
00473 }
00474
00475 inline
00476 void
00477 sc_event::notify_next_delta()
00478 {
00479
00480 sc_process_b* m_proc = m_simc->get_curr_proc();
00481
00482 if( m_notify_type != NONE ) {
00483 SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00484 }
00485
00486
00487 set_notify_timestamp( m_proc->get_timestamp() );
00488
00489
00490 m_delta_event_index = m_simc->add_delta_event( this );
00491 m_notify_type = DELTA;
00492 }
00493
00494 inline
00495 void
00496 sc_event::notify_delayed( double v, sc_time_unit tu )
00497 {
00498 notify_delayed( sc_time( v, tu, m_simc ) );
00499 }
00500
00501
00502 inline
00503 void
00504 sc_event::add_static( sc_method_handle method_h ) const
00505 {
00506 m_methods_static.push_back( method_h );
00507 }
00508
00509 inline
00510 void
00511 sc_event::add_static( sc_thread_handle thread_h ) const
00512 {
00513 m_threads_static.push_back( thread_h );
00514 }
00515
00516 inline
00517 void
00518 sc_event::add_dynamic( sc_method_handle method_h ) const
00519 {
00520 m_methods_dynamic.push_back( method_h );
00521 }
00522
00523 inline
00524 void
00525 sc_event::add_dynamic( sc_thread_handle thread_h ) const
00526 {
00527
00528 m_threads_dynamic.push_back( thread_h );
00529 }
00530
00531
00532
00533
00534
00535
00536 extern void notify( sc_event& e );
00537 extern void notify( const sc_time& t, sc_event& e );
00538 extern void notify( double v, sc_time_unit tu, sc_event& e );
00539
00540
00541
00542
00543 inline
00544 sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
00545 : m_events()
00546 , m_and_list( and_list_ )
00547 , m_auto_delete( auto_delete_ )
00548 , m_busy( 0 )
00549 {
00550 }
00551
00552 inline
00553 sc_event_list::sc_event_list( const sc_event& e,
00554 bool and_list_,
00555 bool auto_delete_ )
00556 : m_events()
00557 , m_and_list( and_list_ )
00558 , m_auto_delete( auto_delete_ )
00559 , m_busy(0)
00560 {
00561 m_events.push_back( &e );
00562 }
00563
00564 inline
00565 sc_event_list::sc_event_list( sc_event_list const & that )
00566 : m_events()
00567 , m_and_list( that.m_and_list )
00568 , m_auto_delete( false )
00569 , m_busy( 0 )
00570 {
00571 move_from( that );
00572 that.auto_delete();
00573 }
00574
00575 inline
00576 sc_event_list&
00577 sc_event_list::operator=( sc_event_list const & that )
00578 {
00579 if( m_busy )
00580 report_invalid_modification();
00581
00582 move_from( that );
00583 that.auto_delete();
00584
00585 return *this;
00586 }
00587
00588 inline
00589 sc_event_list::~sc_event_list()
00590 {
00591 if( m_busy )
00592 report_premature_destruction();
00593 }
00594
00595 inline
00596 void
00597 sc_event_list::swap( sc_event_list& that )
00598 {
00599 if( busy() || that.busy() )
00600 report_invalid_modification();
00601 m_events.swap( that.m_events );
00602 }
00603
00604 inline
00605 void
00606 sc_event_list::move_from( sc_event_list const& that )
00607 {
00608 if( that.temporary() ) {
00609 swap( const_cast<sc_event_list&>(that) );
00610 } else {
00611 m_events = that.m_events;
00612 }
00613 }
00614
00615 inline
00616 int
00617 sc_event_list::size() const
00618 {
00619 return m_events.size();
00620 }
00621
00622 inline
00623 bool
00624 sc_event_list::and_list() const
00625 {
00626 return m_and_list;
00627 }
00628
00629
00630 inline
00631 bool
00632 sc_event_list::busy() const
00633 {
00634 return m_busy != 0;
00635 }
00636
00637
00638 inline
00639 bool
00640 sc_event_list::temporary() const
00641 {
00642 return m_auto_delete && ! m_busy;
00643 }
00644
00645 inline
00646 void
00647 sc_event_list::auto_delete() const
00648 {
00649 if( m_busy ) {
00650 --m_busy;
00651 }
00652 if( ! m_busy && m_auto_delete ) {
00653 delete this;
00654 }
00655 }
00656
00657
00658
00659
00660
00661 inline
00662 sc_event_or_list::sc_event_or_list()
00663 : sc_event_list( false )
00664 {}
00665
00666 inline
00667 sc_event_or_list::sc_event_or_list( const sc_event& e )
00668 : sc_event_list( false )
00669 {
00670 push_back( e );
00671 }
00672
00673 inline
00674 sc_event_or_list::sc_event_or_list( bool auto_delete_ )
00675 : sc_event_list( false, auto_delete_ )
00676 {}
00677
00678 inline
00679 sc_event_or_list&
00680 sc_event_or_list::operator |= ( const sc_event& e )
00681 {
00682 if( busy() )
00683 report_invalid_modification();
00684
00685 push_back( e );
00686 return *this;
00687 }
00688
00689 inline
00690 sc_event_or_list&
00691 sc_event_or_list::operator |= ( const sc_event_or_list& el )
00692 {
00693 if( busy() )
00694 report_invalid_modification();
00695
00696 push_back( el );
00697 return *this;
00698 }
00699
00700 inline
00701 sc_event_or_expr
00702 sc_event_or_list::operator | ( const sc_event& e2 ) const
00703 {
00704 sc_event_or_expr expr;
00705 expr.push_back( *this );
00706 expr.push_back( e2 );
00707 return expr;
00708 }
00709
00710 inline
00711 sc_event_or_expr
00712 sc_event_or_list::operator | ( const sc_event_or_list& e2 ) const
00713 {
00714 sc_event_or_expr expr;
00715 expr.push_back( *this );
00716 expr.push_back( e2 );
00717 return expr;
00718 }
00719
00720
00721
00722
00723 inline
00724 sc_event_or_expr
00725 sc_event::operator | ( const sc_event& e2 ) const
00726 {
00727 sc_event_or_expr expr;
00728 expr.push_back( *this );
00729 expr.push_back( e2 );
00730 return expr;
00731 }
00732
00733 inline
00734 sc_event_or_expr
00735 sc_event::operator | ( const sc_event_or_list& e2 ) const
00736 {
00737 sc_event_or_expr expr;
00738 expr.push_back( *this );
00739 expr.push_back( e2 );
00740 return expr;
00741 }
00742
00743
00744
00745 inline
00746 sc_event_or_expr
00747 operator | ( sc_event_or_expr expr, sc_event const & e )
00748 {
00749 expr.push_back( e );
00750 return expr;
00751 }
00752
00753 inline
00754 sc_event_or_expr
00755 operator | ( sc_event_or_expr expr, sc_event_or_list const & el )
00756 {
00757 expr.push_back( el );
00758 return expr;
00759 }
00760
00761 inline
00762 void
00763 sc_event_or_list::swap( sc_event_or_list & that )
00764 {
00765 sc_event_list::swap( that );
00766 }
00767
00768
00769
00770
00771
00772 inline
00773 sc_event_and_list::sc_event_and_list()
00774 : sc_event_list( true )
00775 {}
00776
00777 inline
00778 sc_event_and_list::sc_event_and_list( const sc_event& e )
00779 : sc_event_list( true )
00780 {
00781 push_back( e );
00782 }
00783
00784 inline
00785 sc_event_and_list::sc_event_and_list( bool auto_delete_ )
00786 : sc_event_list( true, auto_delete_ )
00787 {}
00788
00789 inline
00790 void
00791 sc_event_and_list::swap( sc_event_and_list & that )
00792 {
00793 sc_event_list::swap( that );
00794 }
00795
00796
00797 inline
00798 sc_event_and_list&
00799 sc_event_and_list::operator &= ( const sc_event& e )
00800 {
00801 if( busy() )
00802 report_invalid_modification();
00803
00804 push_back( e );
00805 return *this;
00806 }
00807
00808 inline
00809 sc_event_and_list&
00810 sc_event_and_list::operator &= ( const sc_event_and_list& el )
00811 {
00812 if( busy() )
00813 report_invalid_modification();
00814
00815 push_back( el );
00816 return *this;
00817 }
00818
00819 inline
00820 sc_event_and_expr
00821 sc_event_and_list::operator & ( const sc_event& e )
00822 {
00823 sc_event_and_expr expr;
00824 expr.push_back( *this );
00825 expr.push_back( e );
00826 return expr;
00827 }
00828
00829 inline
00830 sc_event_and_expr
00831 sc_event_and_list::operator & ( const sc_event_and_list& el )
00832 {
00833 sc_event_and_expr expr;
00834 expr.push_back( *this );
00835 expr.push_back( el );
00836 return expr;
00837 }
00838
00839
00840
00841 inline
00842 sc_event_and_expr
00843 sc_event::operator & ( const sc_event& e2 ) const
00844 {
00845 sc_event_and_expr expr;
00846 expr.push_back( *this );
00847 expr.push_back( e2 );
00848 return expr;
00849 }
00850
00851 inline
00852 sc_event_and_expr
00853 sc_event::operator & ( const sc_event_and_list& e2 ) const
00854 {
00855 sc_event_and_expr expr;
00856 expr.push_back( *this );
00857 expr.push_back( e2 );
00858 return expr;
00859 }
00860
00861
00862
00863 inline
00864 sc_event_and_expr
00865 operator & ( sc_event_and_expr expr, sc_event const & e )
00866 {
00867 expr.push_back( e );
00868 return expr;
00869 }
00870
00871 inline
00872 sc_event_and_expr
00873 operator & ( sc_event_and_expr expr, sc_event_and_list const & el )
00874 {
00875 expr.push_back( el );
00876 return expr;
00877 }
00878
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 #endif
00952
00953