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 #ifndef SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
00032 #define SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
00033 
00034 #if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS ) \
00035  || defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
00036 #  define SC_HAS_PHASE_CALLBACKS_ 1
00037 #else
00038 #  define SC_HAS_PHASE_CALLBACKS_ 0
00039 #endif
00040 
00041 #include "sysc/kernel/sc_simcontext.h"
00042 #include "sysc/kernel/sc_object_int.h"
00043 #include "sysc/kernel/sc_status.h"
00044 
00045 #include <vector>
00046 
00047 namespace sc_core {
00048 
00049 class sc_simcontext;
00050 class sc_object;
00051 
00052 class sc_phase_callback_registry
00053 {
00054 public:
00055     typedef sc_phase_callback_registry this_type;
00056     typedef sc_object                  cb_type;
00057     typedef cb_type::phase_cb_mask     mask_type;
00058 
00059     struct entry
00060     {
00061         cb_type*  target;
00062         mask_type mask;
00063     };
00064 
00065     friend class sc_simcontext;
00066     friend class sc_object;
00067 
00068 private: 
00069 
00070     explicit
00071     sc_phase_callback_registry( sc_simcontext& simc );
00072 
00073     ~sc_phase_callback_registry();
00074 
00075     
00076 
00077     bool construction_done()   const; 
00078     void elaboration_done()    const;
00079     void initialization_done() const;
00080     void start_simulation()    const;
00081 
00082     void evaluation_done()     const;
00083     void update_done()         const;
00084     void before_timestep()     const;
00085 
00086     void simulation_paused()   const;
00087     void simulation_stopped()  const;
00088     void simulation_done()     const;
00089 
00090 
00091     
00092 
00093     mask_type register_callback( cb_type&, mask_type mask );
00094     mask_type unregister_callback( cb_type&, mask_type mask );
00095 
00096     
00097     void do_callback( sc_status ) const;
00098 
00099 private:
00100     typedef std::vector<entry>    storage_type;
00101     typedef std::vector<cb_type*> single_storage_type;
00102 
00103 #if SC_HAS_PHASE_CALLBACKS_
00104 
00105     
00106     struct scoped_status
00107     {
00108         scoped_status( sc_status& ref, sc_status s )
00109           : ref_(ref), prev_(ref) { ref_ = s;}
00110         ~scoped_status() { ref_ = prev_; }
00111     private:
00112         sc_status& ref_;
00113         sc_status  prev_;
00114     }; 
00115 
00116     mask_type validate_mask( cb_type&, mask_type, bool warn );
00117 
00118 private:
00119 
00120     sc_simcontext*        m_simc;
00121     storage_type          m_cb_vec;            
00122 #if 0
00123     single_storage_type   m_cb_eval_vec;     
00124 #endif
00125     single_storage_type   m_cb_update_vec;   
00126     single_storage_type   m_cb_timestep_vec; 
00127 
00128 #endif // SC_HAS_PHASE_CALLBACKS_
00129 
00130 private:
00131     
00132     sc_phase_callback_registry( const this_type& );
00133     this_type& operator=(const this_type&);
00134 
00135 }; 
00136 
00137 
00138 
00139 
00140 
00141 inline bool
00142 sc_phase_callback_registry::construction_done() const
00143 {
00144 #if SC_HAS_PHASE_CALLBACKS_
00145     do_callback( SC_BEFORE_END_OF_ELABORATION );
00146 #endif
00147     return false;
00148 }
00149 
00150 inline void
00151 sc_phase_callback_registry::elaboration_done() const
00152 {
00153 #if SC_HAS_PHASE_CALLBACKS_
00154     do_callback( SC_END_OF_ELABORATION );
00155 #endif
00156 }
00157 
00158 inline void
00159 sc_phase_callback_registry::start_simulation() const
00160 {
00161 #if SC_HAS_PHASE_CALLBACKS_
00162     do_callback( SC_START_OF_SIMULATION );
00163 #endif
00164 }
00165 
00166 inline void
00167 sc_phase_callback_registry::initialization_done() const
00168 {
00169 #if SC_HAS_PHASE_CALLBACKS_
00170     scoped_status scope( m_simc->m_simulation_status
00171                        , SC_END_OF_INITIALIZATION );
00172 
00173     do_callback( SC_END_OF_INITIALIZATION );
00174 #endif
00175 }
00176 
00177 inline void
00178 sc_phase_callback_registry::simulation_paused() const
00179 {
00180 #if SC_HAS_PHASE_CALLBACKS_
00181     do_callback( SC_PAUSED );
00182 #endif
00183 }
00184 
00185 inline void
00186 sc_phase_callback_registry::simulation_stopped() const
00187 {
00188 #if SC_HAS_PHASE_CALLBACKS_
00189     do_callback( SC_STOPPED );
00190 #endif
00191 }
00192 
00193 inline void
00194 sc_phase_callback_registry::simulation_done() const
00195 {
00196 #if SC_HAS_PHASE_CALLBACKS_
00197     do_callback( SC_END_OF_SIMULATION );
00198 #endif
00199 }
00200 
00201 
00202 
00203 #if 0
00204 inline void
00205 sc_phase_callback_registry::evaluation_done() const
00206 {
00207 #if SC_HAS_PHASE_CALLBACKS_
00208 
00209     if( !m_cb_eval_vec.size() ) return;
00210 
00211     typedef single_storage_type::const_iterator it_type;
00212     single_storage_type const & vec = m_cb_eval_vec;
00213 
00214     scoped_status scope( m_simc->m_simulation_status
00215                        , SC_END_OF_EVALUATION );
00216 
00217     for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
00218         (*it)->do_simulation_phase_callback();
00219 #endif
00220 }
00221 #endif
00222 
00223 inline void
00224 sc_phase_callback_registry::update_done() const
00225 {
00226 #if SC_HAS_PHASE_CALLBACKS_
00227 
00228     if( !m_cb_update_vec.size() ) return;
00229 
00230     typedef single_storage_type::const_iterator it_type;
00231     single_storage_type const & vec = m_cb_update_vec;
00232 
00233     scoped_status scope( m_simc->m_simulation_status
00234                        , SC_END_OF_UPDATE );
00235 
00236     for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
00237         (*it)->do_simulation_phase_callback();
00238 #endif
00239 }
00240 
00241 inline void
00242 sc_phase_callback_registry::before_timestep() const
00243 {
00244 #if SC_HAS_PHASE_CALLBACKS_
00245 
00246     if( !m_cb_timestep_vec.size() ) return;
00247 
00248     typedef single_storage_type::const_iterator it_type;
00249     single_storage_type const & vec = m_cb_timestep_vec;
00250 
00251     scoped_status scope( m_simc->m_simulation_status
00252                        , SC_BEFORE_TIMESTEP );
00253 
00254     for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
00255         (*it)->do_simulation_phase_callback();
00256 #endif
00257 }
00258 
00259 
00260 
00261 } 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 #endif 
00273 
00274