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
00037 #ifndef RC_PROCESS_SUPPORT_H_
00038 #define RC_PROCESS_SUPPORT_H_
00039
00040 #include "ReChannel/core/rc_reconfigurable.h"
00041 #include "ReChannel/core/rc_non_reconfigurable.h"
00042 #include "ReChannel/core/rc_reset_channel_if.h"
00043
00044 namespace ReChannel {
00045
00046 class rc_process_reset;
00047
00048 namespace internals {
00049
00068 class process_support
00069 : public sc_prim_channel
00070 {
00071 private:
00072 class process_info;
00073
00074 private:
00075 typedef rc_hash_map<sc_object*, process_info*> process_info_map;
00076
00077 public:
00078 process_support();
00079
00080 inline bool has_reconfigurable_context() const
00081 { return (&p_reconf != &rc_non_reconfigurable::get_instance()); }
00082
00083 inline bool has_non_reconfigurable_context() const
00084 { return (&p_reconf == &rc_non_reconfigurable::get_instance()); }
00085
00086 inline rc_reconfigurable& get_context() const
00087 { return p_reconf; }
00088
00089 inline rc_reconfigurable* get_reconfigurable_context() const;
00090
00091 void declare_process(
00092 const sc_object& host,
00093 const boost::function<void (void)>& declare_proc_callback,
00094 const boost::function<void (void)>& func, sc_sensitive& sensitive,
00095 bool is_thread=false, bool dont_initialize=false,
00096 bool has_sync_reset=false);
00097
00098 void method_process();
00099
00100 void thread_process();
00101
00102 void dont_initialize(const sc_object& host) const;
00103
00104
00105 rc_process_handle rc_spawn(
00106 boost::function<void (void)> func, const char* name_p=NULL,
00107 rc_spawn_options* opt_p=NULL);
00108
00109 void terminate();
00110
00111 bool reset_signal_is(
00112 const sc_object& host, const sc_in<bool>& port_,
00113 bool active_level);
00114
00115 bool reset_signal_is(
00116 const sc_object& host, const sc_signal<bool>& signal_,
00117 bool active_level);
00118
00119 const sc_signal<bool>* reset_channel_is(
00120 const sc_object& host, rc_reset_channel_if& reset_,
00121 bool active_level);
00122
00123 void reset_is(const sc_object& host, rc_process_reset& process_reset);
00124
00125 void set_sync_reset(const sc_object& host, bool b) const;
00126
00127 rc_process_behavior_change disable_process_control() const;
00128
00129 protected:
00130 void before_end_of_elaboration();
00131
00132 private:
00133 process_info* _rc_find_process_info(sc_object* proc_obj) const;
00134
00135 process_info* _rc_fetch_process_info(sc_object* proc_obj);
00136
00137 bool _rc_check_valid_last_proc(const sc_object& host) const;
00138
00139 private:
00140 static rc_reconfigurable& _rc_find_context(sc_object* start_search);
00141
00142 static inline void register_process_control(
00143 const rc_reset_channel_if& reset_channel,
00144 rc_process_control& pctrl, bool active_level)
00145 { reset_channel.register_process_control(pctrl, active_level); }
00146
00147 static inline void unregister_process_control(
00148 const rc_reset_channel_if& reset_channel,
00149 rc_process_control& pctrl)
00150 { reset_channel.unregister_process_control(pctrl); }
00151
00152 static inline bool get_current_level(
00153 const rc_reset_channel_if& reset_channel)
00154 { return reset_channel.get_current_level(); }
00155
00156 private:
00157 rc_reconfigurable& p_reconf;
00158 process_info_map p_reconf_pinfo_map;
00159 process_info* p_last_pinfo;
00160 const sc_object* p_last_host;
00161 unsigned int p_last_host_child_count;
00162 };
00163
00168 class process_support::process_info
00169 {
00170 private:
00171 typedef std::vector<const rc_reset_channel_if*> reset_channel_vector;
00172 typedef std::vector<const sc_in<bool>*> reset_port_vector;
00173 typedef internals::reset_signal reset_signal;
00174 typedef std::map<const sc_signal_in_if<bool>*, reset_signal*>
00175 reset_signal_map;
00176 public:
00177 process_info(
00178 boost::function<void (void)> func_,
00179 const rc_process_control& parent_pctrl, bool is_thread_=false,
00180 bool is_dont_initialize=false, bool has_sync_reset=false);
00181
00182 inline bool is_thread() const
00183 { return p_is_thread; }
00184
00185 inline bool is_dont_initialize() const
00186 { return p_is_dont_initialize; }
00187
00188 inline void set_dont_initialize(bool b)
00189 { p_is_dont_initialize = b; }
00190
00191 inline bool has_sync_reset() const
00192 { return process_control.is_deactivate_silently(); }
00193
00194 inline void set_sync_reset(bool b)
00195 { process_control.set_deactivate_silently(b); }
00196
00197 inline bool is_init_run() const
00198 { return p_is_init_run; }
00199
00200 inline void set_init_run(bool b)
00201 { p_is_init_run = b; }
00202
00203 void register_reset_channel(
00204 const rc_reset_channel_if& reset_channel, bool active_level);
00205
00206 void register_reset_interface(
00207 const sc_signal_in_if<bool>& reset_interface, bool active_level);
00208
00209 void register_reset_signal(
00210 const sc_signal<bool>& reset_signal, bool active_level);
00211
00212 void register_reset_port(
00213 const sc_in<bool>& reset_port, bool active_level);
00214
00215 void register_reset_port_interfaces();
00216
00217 void update_process_control_state();
00218
00219 ~process_info();
00220
00221 private:
00222 static const rc_reset_channel_if& _rc_get_reset_channel(
00223 const sc_signal_in_if<bool>& signal_interface);
00224
00225 static void _rc_reset_updater_proc(
00226 const sc_signal_in_if<bool>& from_, reset_signal& to_);
00227
00228 public:
00229 boost::function<void (void)> func;
00230 rc_process_control process_control;
00231
00232 private:
00233 bool p_is_thread : 1;
00234 bool p_is_dont_initialize : 1;
00235 bool p_is_init_run : 1;
00236 reset_channel_vector p_reset_channels[2];
00237 reset_port_vector p_reset_ports[2];
00238
00239 private:
00240 static reset_signal_map p_reset_signal_map;
00241 };
00242
00243 }
00244
00266 class rc_process_reset
00267 : public sc_prim_channel,
00268 protected rc_reset_channel_if
00269 {
00270 friend class internals::process_support;
00271
00272 private:
00273 typedef std::set<rc_process_control*> pctrl_set;
00274
00275 public:
00276 explicit rc_process_reset();
00277
00278 explicit rc_process_reset(const char* name_);
00279
00280 public:
00284 virtual void trigger();
00285
00286 protected:
00287
00288 virtual void register_process_control(
00289 rc_process_control& pctrl, bool active_level) const;
00290
00291
00292 virtual void unregister_process_control(
00293 rc_process_control& pctrl) const;
00294
00295
00296 virtual bool get_current_level() const
00297 { return false; }
00298
00299
00300 virtual const sc_signal<bool>* get_underlying_reset_signal() const
00301 { return NULL; }
00302
00303 private:
00304 mutable pctrl_set p_pctrl_set;
00305 };
00306
00307
00308
00309 namespace internals {
00310
00311 inline
00312 rc_reconfigurable* process_support::get_reconfigurable_context() const
00313 {
00314 if (&p_reconf != &rc_non_reconfigurable::get_instance()) {
00315 return &p_reconf;
00316 } else {
00317 return NULL;
00318 }
00319 }
00320
00321 }
00322
00323 }
00324
00325
00326
00327 #define RC_HAS_RECONFIGURABLE_PROCESS(user_module_name) \
00328 SC_HAS_PROCESS(user_module_name); \
00329 private: \
00330 internals::process_support \
00331 _rc_process_support; \
00332 void _rc_declare_method() \
00333 { SC_METHOD(_rc_method_process); } \
00334 void _rc_declare_thread() \
00335 { SC_THREAD(_rc_thread_process); } \
00336 void _rc_method_process() \
00337 { this->_rc_process_support.method_process(); } \
00338 void _rc_thread_process() \
00339 { this->_rc_process_support.thread_process(); } \
00340 protected: \
00341 inline void next_trigger() \
00342 { rc_next_trigger(); } \
00343 inline void next_trigger(const sc_event& e) \
00344 { rc_next_trigger(e); } \
00345 inline void next_trigger(sc_event_or_list& el) \
00346 { rc_next_trigger(el); } \
00347 inline void next_trigger(sc_event_and_list& el) \
00348 { rc_next_trigger(el); } \
00349 inline void next_trigger(const sc_time& t) \
00350 { rc_next_trigger(t); } \
00351 inline void next_trigger(double v, sc_time_unit tu) \
00352 { rc_next_trigger(v, tu); } \
00353 inline void next_trigger(const sc_time& t, const sc_event& e) \
00354 { rc_next_trigger(t, e); } \
00355 inline void next_trigger( \
00356 double v, sc_time_unit tu, const sc_event& e) \
00357 { rc_next_trigger(v, tu, e); } \
00358 inline void next_trigger(const sc_time& t, sc_event_or_list& el) \
00359 { rc_next_trigger(t, el); } \
00360 inline void next_trigger( \
00361 double v, sc_time_unit t, sc_event_or_list& el) \
00362 { rc_next_trigger(v, t, el); } \
00363 inline void next_trigger(const sc_time& t, sc_event_and_list& el) \
00364 { rc_next_trigger(t, el); } \
00365 inline void next_trigger( \
00366 double v, sc_time_unit tu, sc_event_and_list& el) \
00367 { rc_next_trigger(v, tu, el); } \
00368 inline void wait() \
00369 { rc_wait(); } \
00370 inline void wait(int n) \
00371 { rc_wait(n); } \
00372 inline void wait(const sc_event& e) \
00373 { rc_wait(e); } \
00374 inline void wait(sc_event_or_list& el) \
00375 { rc_wait(el); } \
00376 inline void wait(sc_event_and_list& el) \
00377 { rc_wait(el); } \
00378 inline void wait(const sc_time& t) \
00379 { rc_wait(t); } \
00380 inline void wait(double v, sc_time_unit tu) \
00381 { rc_wait(v, tu); } \
00382 inline void wait(const sc_time& t, const sc_event& e) \
00383 { rc_wait(t, e); } \
00384 inline void wait(double v, sc_time_unit tu, const sc_event& e) \
00385 { rc_wait(v, tu, e); } \
00386 inline void wait(const sc_time& t, sc_event_or_list& el) \
00387 { rc_wait(t, el); } \
00388 inline void wait(double v, sc_time_unit t, sc_event_or_list& el) \
00389 { rc_wait(v, t, el); } \
00390 inline void wait(const sc_time& t, sc_event_and_list& el) \
00391 { rc_wait(t, el); } \
00392 inline void wait( \
00393 double v, sc_time_unit tu, sc_event_and_list& el) \
00394 { rc_wait(v, tu, el); } \
00395 template<class _rc_T_param> \
00396 inline rc_process_handle rc_spawn( \
00397 _rc_T_param object, const char* name_p=NULL, \
00398 rc_spawn_options* opt_p=NULL) \
00399 { \
00400 return this->_rc_process_support.rc_spawn( \
00401 object, name_p, opt_p); \
00402 } \
00403 inline bool rc_is_reconfigurable() const \
00404 { \
00405 return this->_rc_process_support.has_reconfigurable_context(); \
00406 } \
00407 inline void rc_terminate() \
00408 { this->_rc_process_support.terminate(); } \
00409 public: \
00410 inline void dont_initialize() \
00411 { \
00412 this->_rc_process_support.dont_initialize(*this); \
00413 sc_module::dont_initialize(); \
00414 } \
00415 inline void reset_signal_is( \
00416 const sc_in<bool>& reset_port, bool active_level) \
00417 { \
00418 bool success = this->_rc_process_support.reset_signal_is( \
00419 *this, reset_port, active_level); \
00420 if (!success) { \
00421 sc_module::reset_signal_is(reset_port, active_level); \
00422 } \
00423 } \
00424 inline void reset_signal_is( \
00425 const sc_signal<bool>& reset_signal, bool active_level) \
00426 { \
00427 bool success = this->_rc_process_support.reset_signal_is( \
00428 *this, reset_signal, active_level); \
00429 if (!success) { \
00430 sc_module::reset_signal_is(reset_signal, active_level); \
00431 } \
00432 } \
00433 inline void reset_signal_is( \
00434 rc_reset_channel_if& reset_channel, bool active_level) \
00435 { \
00436 const sc_signal<bool>* reset_signal = \
00437 this->_rc_process_support.reset_channel_is( \
00438 *this, reset_channel, active_level); \
00439 if (reset_signal != NULL) { \
00440 sc_module::reset_signal_is(*reset_signal, active_level); \
00441 } \
00442 } \
00443 inline void reset_is(rc_process_reset& process_reset) \
00444 { this->_rc_process_support.reset_is(*this, process_reset); } \
00445 inline void rc_set_sync_reset() \
00446 { this->_rc_process_support.set_sync_reset(*this, true); } \
00447 inline void rc_set_async_reset() \
00448 { this->_rc_process_support.set_sync_reset(*this, false); } \
00449 typedef user_module_name RC_CURRENT_USER_MODULE
00450
00451 #define RC_RECONFIGURABLE_METHOD(func) \
00452 if (true) { \
00453 if (this->_rc_process_support.has_reconfigurable_context()) { \
00454 this->_rc_process_support.declare_process( \
00455 *this, \
00456 boost::bind( \
00457 &RC_CURRENT_USER_MODULE::_rc_declare_method, this), \
00458 boost::bind( \
00459 &RC_CURRENT_USER_MODULE::func, this), \
00460 this->sensitive); \
00461 } else { \
00462 SC_METHOD(func); \
00463 } \
00464 } else (void)0
00465
00466 #define RC_RECONFIGURABLE_THREAD(func) \
00467 if (true) { \
00468 this->_rc_process_support.declare_process( \
00469 *this, \
00470 boost::bind( \
00471 &RC_CURRENT_USER_MODULE::_rc_declare_thread, this), \
00472 boost::bind( \
00473 &RC_CURRENT_USER_MODULE::func, this), \
00474 this->sensitive, true, false, false); \
00475 } else (void)0
00476
00477 #define RC_RECONFIGURABLE_CTHREAD(func, edge) \
00478 if (true) { \
00479 this->_rc_process_support.declare_process( \
00480 *this, \
00481 boost::bind( \
00482 &RC_CURRENT_USER_MODULE::_rc_declare_thread, this), \
00483 boost::bind( \
00484 &RC_CURRENT_USER_MODULE::func, this), \
00485 this->sensitive, true, true, true); \
00486 this->sensitive << edge; \
00487 } else (void)0
00488
00489 #define RC_NO_RECONFIGURABLE_PROCESS_RESET(pbc_name) \
00490 for(rc_process_behavior_change pbc_name = \
00491 this->_rc_process_support.disable_process_control(); \
00492 !pbc_name.is_released(); \
00493 pbc_name.release())
00494
00495 #define RC_HAS_PROCESS(user_module_name) \
00496 RC_HAS_RECONFIGURABLE_PROCESS(user_module_name)
00497
00498 #define RC_METHOD(func) \
00499 RC_RECONFIGURABLE_METHOD(func)
00500
00501 #define RC_THREAD(func) \
00502 RC_RECONFIGURABLE_THREAD(func)
00503
00504 #define RC_CTHREAD(func, edge) \
00505 RC_RECONFIGURABLE_CTHREAD(func, edge)
00506
00507 #define RC_NO_RESET \
00508 RC_NO_RECONFIGURABLE_PROCESS_RESET(_rc_tmp_pbc)
00509
00510 #define _RC_DECLARE_TRANSACTION \
00511 for(rc_transaction _rc_tmp_trans( \
00512 this->_rc_process_support.get_reconfigurable_context()); \
00513 !_rc_tmp_trans.has_ended(); \
00514 _rc_tmp_trans.end())
00515
00516 #define RC_TRANSACTION _RC_DECLARE_TRANSACTION
00517
00518 #endif // RC_PROCESS_SUPPORT_H_
00519
00520
00521
00522
00523