00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #ifndef SC_PRIM_CHANNEL_H
00028 #define SC_PRIM_CHANNEL_H
00029 
00030 #include "sysc/kernel/sc_object.h"
00031 #include "sysc/kernel/sc_wait.h"
00032 #include "sysc/kernel/sc_wait_cthread.h"
00033 
00034 
00035 #include "sysc/kernel/sc_process.h" 
00036 
00037 namespace sc_core {
00038 
00039 
00040 
00046 
00047 
00048 struct chnl_scoped_lock {
00052     CHNL_MTX_TYPE_& m_ref;
00053 
00057     explicit chnl_scoped_lock( CHNL_MTX_TYPE_& mtx ): m_ref( mtx )
00058     { 
00059         sc_process_b* cp = sc_get_current_process_b();
00060         if (cp) 
00061             cp->lock_and_push( &m_ref ); 
00062     }
00063 
00067     ~chnl_scoped_lock()
00068     {
00069         sc_process_b* cp = sc_get_current_process_b();
00070         if (cp) 
00071             cp->pop_and_unlock( &m_ref ); 
00072     }
00073 };
00074 
00075 
00081 class sc_prim_channel
00082 : public sc_object
00083 {
00084     friend class sc_prim_channel_registry;
00085 
00086 public:
00087     enum { list_end = 0xdb };
00088 public:
00089     virtual const char* kind() const
00090         { return "sc_prim_channel"; }
00091 
00092     inline bool update_requested() 
00093     {
00094         
00095         chnl_scoped_lock lock( m_mutex );
00096 
00097         return m_update_next_p != (sc_prim_channel*)list_end;
00098         
00099     }
00100 
00101     
00102     inline void request_update();
00103 
00104     
00105     
00106     void async_request_update();
00107 
00108 protected:
00109 
00110     
00111     sc_prim_channel();
00112     explicit sc_prim_channel( const char* );
00113 
00114     
00115     virtual ~sc_prim_channel();
00116 
00123     
00124     virtual void update();
00125 
00126     
00127     virtual void before_end_of_elaboration();
00128 
00129     
00130     virtual void end_of_elaboration();
00131 
00132     
00133     virtual void start_of_simulation();
00134 
00135     
00136     virtual void end_of_simulation();
00137 
00138 protected:
00139 
00140     
00141 
00142     
00143 
00148     
00149     void wait( int seg_id )
00150         { sc_core::wait( seg_id, simcontext() ); }
00151 
00152 
00153     
00154 
00159     
00160     void wait( const sc_event& e, int seg_id )
00161         { sc_core::wait( e, seg_id, simcontext() ); }
00162 
00167     
00168     void wait( const sc_event_or_list& el, int seg_id )
00169         { sc_core::wait( el, seg_id, simcontext() ); }
00170 
00175     
00176     void wait( const sc_event_and_list& el, int seg_id )
00177         { sc_core::wait( el, seg_id, simcontext() ); }
00178 
00183     
00184     void wait( const sc_time& t, int seg_id )
00185         { sc_core::wait( t, seg_id, simcontext() ); }
00186 
00191     
00192     void wait( double v, sc_time_unit tu, int seg_id )
00193         { sc_core::wait( sc_time( v, tu, simcontext() ), seg_id, 
00194                          simcontext() ); }
00195 
00200     
00201     void wait( const sc_time& t, const sc_event& e, int seg_id )
00202         { sc_core::wait( t, e, seg_id, simcontext() ); }
00203 
00208     
00209     void wait( double v, sc_time_unit tu, const sc_event& e, int seg_id )
00210         { sc_core::wait( sc_time( v, tu, simcontext() ), e, seg_id, 
00211                          simcontext() ); }
00212 
00217     
00218     void wait( const sc_time& t, const sc_event_or_list& el, int seg_id )
00219         { sc_core::wait( t, el, seg_id, simcontext() ); }
00220 
00225     
00226     void wait( double v, sc_time_unit tu, const sc_event_or_list& el, 
00227                int seg_id )
00228         { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id, 
00229                          simcontext() ); }
00230 
00235     
00236     void wait( const sc_time& t, const sc_event_and_list& el, int seg_id )
00237         { sc_core::wait( t, el, seg_id, simcontext() ); }
00238 
00243     
00244     void wait( double v, sc_time_unit tu, const sc_event_and_list& el, 
00245                int seg_id )
00246         { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id, 
00247                          simcontext() ); }
00248 
00253     
00254     void wait( int n, int seg_id )
00255         { sc_core::wait( n, seg_id, simcontext() ); }
00256 
00257 
00258     
00259 
00264     
00265     void next_trigger( int seg_id )
00266         { sc_core::next_trigger( seg_id, simcontext() ); }
00267 
00268 
00269     
00270 
00275     
00276     void next_trigger( const sc_event& e, int seg_id )
00277         { sc_core::next_trigger( e, seg_id, simcontext() ); }
00278 
00283     
00284     void next_trigger( const sc_event_or_list& el, int seg_id )
00285         { sc_core::next_trigger( el, seg_id, simcontext() ); }
00286 
00291     
00292     void next_trigger( const sc_event_and_list& el, int seg_id )
00293         { sc_core::next_trigger( el, seg_id, simcontext() ); }
00294 
00299     
00300     void next_trigger( const sc_time& t, int seg_id )
00301         { sc_core::next_trigger( t, seg_id, simcontext() ); }
00302 
00307     
00308     void next_trigger( double v, sc_time_unit tu, int seg_id )
00309         {sc_core::next_trigger( sc_time( v, tu, simcontext() ), seg_id, 
00310                                 simcontext() );}
00311 
00316     
00317     void next_trigger( const sc_time& t, const sc_event& e, int seg_id )
00318         { sc_core::next_trigger( t, e, seg_id, simcontext() ); }
00319 
00324     
00325     void next_trigger( double v, sc_time_unit tu, const sc_event& e, 
00326                        int seg_id )
00327         { sc_core::next_trigger( 
00328             sc_time( v, tu, simcontext() ), e, seg_id, simcontext() ); }
00329 
00334     
00335     void next_trigger( const sc_time& t, const sc_event_or_list& el, 
00336                        int seg_id )
00337         { sc_core::next_trigger( t, el, seg_id, simcontext() ); }
00338 
00343     
00344     void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el, 
00345                        int seg_id )
00346         { sc_core::next_trigger( 
00347             sc_time( v, tu, simcontext() ), el, seg_id, simcontext() ); }
00348 
00353     
00354     void next_trigger( const sc_time& t, const sc_event_and_list& el, 
00355                        int seg_id )
00356         { sc_core::next_trigger( t, el, seg_id, simcontext() ); }
00357 
00362     
00363     void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el, 
00364                        int seg_id )
00365         { sc_core::next_trigger( 
00366             sc_time( v, tu, simcontext() ), el, seg_id, simcontext() ); }
00367 
00368 
00369     
00370 
00371     bool timed_out()
00372         { return sc_core::timed_out( simcontext() ); }
00373 
00374 
00375 #if 0 // @@@@####
00376     
00377     sc_dt::uint64 delta_count()
00378         { return simcontext()->m_delta_count; }
00379 #endif
00380 
00381 private:
00382 
00383     
00384     void perform_update();
00385 
00386     
00387     void construction_done();
00388 
00389     
00390     void elaboration_done();
00391 
00392     
00393     void start_simulation();
00394 
00395     
00396     void simulation_done();
00397 
00398     
00399     sc_prim_channel( const sc_prim_channel& );
00400     sc_prim_channel& operator = ( const sc_prim_channel& );
00401 
00402 private:
00403 
00404     sc_prim_channel_registry* m_registry;          
00405     sc_prim_channel*          m_update_next_p;     
00406 
00407 protected:
00408 
00412     
00413     mutable CHNL_MTX_TYPE_ m_mutex;
00414 };
00415 
00416 
00417 
00425 class sc_prim_channel_registry
00426 {
00427     friend class sc_simcontext;
00428 
00429 public:
00430 
00431     void insert( sc_prim_channel& );
00432     void remove( sc_prim_channel& );
00433 
00434 
00435     int size() const
00436         { return m_prim_channel_vec.size(); }
00437 
00438     inline void request_update( sc_prim_channel& );
00439     void async_request_update( sc_prim_channel& );
00440 
00441     bool pending_updates() const
00442     { 
00443         return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end 
00444                || pending_async_updates();
00445     }   
00446 
00447     bool pending_async_updates() const;
00448 
00449 private:
00450 
00451     
00452     explicit sc_prim_channel_registry( sc_simcontext& simc_ );
00453 
00454     
00455     ~sc_prim_channel_registry();
00456 
00457     
00458     void perform_update();
00459 
00460     
00461     bool construction_done();
00462 
00463     
00464     void elaboration_done();
00465 
00466     
00467     void start_simulation();
00468 
00469     
00470     void simulation_done();
00471 
00472     
00473     sc_prim_channel_registry();
00474     sc_prim_channel_registry( const sc_prim_channel_registry& );
00475     sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
00476 
00477 private:
00478     class async_update_list;   
00479 
00480     async_update_list*            m_async_update_list_p; 
00481     int                           m_construction_done;   
00482     std::vector<sc_prim_channel*> m_prim_channel_vec;    
00483     sc_simcontext*                m_simc;                
00484     sc_prim_channel*              m_update_list_p;       
00485 
00489     
00490     CHNL_MTX_TYPE_ m_mutex;
00491 };
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 inline
00504 void
00505 sc_prim_channel_registry::request_update( sc_prim_channel& prim_channel_ )
00506 {
00507     
00508     
00509     chnl_scoped_lock lock( m_mutex );
00510 
00511     prim_channel_.m_update_next_p = m_update_list_p;
00512     m_update_list_p = &prim_channel_;
00513     
00514 }
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 inline
00525 void
00526 sc_prim_channel::request_update()
00527 {
00528     
00529     chnl_scoped_lock lock( m_mutex );
00530 
00531     if( ! m_update_next_p ) {
00532         m_registry->request_update( *this );
00533     }
00534     
00535 }
00536 
00537 
00538 
00539 
00540 
00541 
00542 inline
00543 void
00544 sc_prim_channel::async_request_update() 
00545 {
00546     m_registry->async_request_update(*this);
00547 }
00548 
00549 
00550 
00551 
00552 inline
00553 void
00554 sc_prim_channel::perform_update()
00555 {
00556     update();
00557     m_update_next_p = 0;
00558 }
00559 
00560 
00561 } 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 #endif
00631 
00632