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_ABSTRACT_EXPORTAL_H_
00038 #define RC_ABSTRACT_EXPORTAL_H_
00039
00040 #include "ReChannel/communication/rc_abstract_switch.h"
00041 #include "ReChannel/communication/rc_abstract_interface_wrapper.h"
00042 #include "ReChannel/communication/exportals/rc_wrapper_pool.h"
00043 #include "ReChannel/communication/accessors/rc_accessor.h"
00044 #include "ReChannel/core/rc_reconfigurable.h"
00045 #include "ReChannel/core/rc_non_reconfigurable.h"
00046
00047 namespace ReChannel {
00048
00052 class rc_exportal_base
00053 : public sc_module,
00054 virtual public rc_switch,
00055 virtual protected internals::exportal::wrapper_factory
00056 {
00057 private:
00058 typedef internals::exportal::wrapper_pool wrapper_pool;
00059 typedef internals::exportal::wrapper_handle wrapper_handle;
00060 typedef rc_switch::state_type state_type;
00061
00062 protected:
00063 typedef internals::exportal::wrapper_factory wrapper_factory;
00064
00065 typedef rc_interface_wrapper_base::accessor_base accessor_base_type;
00066 typedef rc_switch::filter_chain filter_chain;
00067
00068 protected:
00069 rc_exportal_base(
00070 const sc_module_name& module_name,
00071 state_type& m_state, unsigned int& m_transaction_count,
00072 wrapper_pool& s_wrapper_pool_);
00073
00075 void _rc_init(accessor_base_type& accessor);
00076
00077 public:
00078
00080 virtual rc_reconfigurable* get_current_reconfigurable() const
00081 { return p_dyn_module; }
00082
00084 virtual sc_interface* get_dynamic_interface() const;
00085
00086 protected:
00087
00089 void bind_dynamic(rc_export_handle export_);
00090
00092 void bind_dynamic(sc_interface& dynamic_if_);
00093
00095 void bind_exclusively(rc_interface_wrapper_base& wrapper);
00096
00098 virtual void rc_on_open() { }
00099
00101 virtual void rc_on_close() { }
00102
00104 virtual void rc_on_refresh_notify() = 0;
00105
00107 virtual void open();
00108
00110 virtual void open(
00111 rc_reconfigurable& module,
00112 const filter_chain& filters = filter_chain());
00113
00115 virtual void close();
00116
00118 virtual void set_undefined();
00119
00121 virtual void refresh_notify()
00122 { this->rc_on_refresh_notify(); }
00123
00125 virtual void register_reconfigurable(
00126 rc_reconfigurable& module, sc_interface& dyn_interface);
00127
00129 virtual void unregister_reconfigurable(rc_reconfigurable& module);
00130
00132 inline rc_process_behavior_change begin_access_callback();
00133
00135 inline void end_access_callback();
00136
00138 void notify_event(const std::string& event_name);
00139
00141 rc_interface_wrapper_base* get_interface_wrapper_base() const;
00142
00143 virtual ~rc_exportal_base() {}
00144
00145 private:
00146
00147 void add_event_forwarder_target(
00148 sc_interface& target_if, rc_event_filter* filter=NULL);
00149
00150 void clear_event_forwarder_targets();
00151
00152 private:
00153
00154
00155
00156 virtual accessor_base_type& _rc_get_static_accessor() = 0;
00157
00158 virtual bool _rc_check_interface_type(sc_interface* dyn_if) const = 0;
00159
00160 virtual bool _rc_check_accessor_if_type(
00161 accessor_base_type* accessor) const = 0;
00162
00163 virtual void _rc_set_interface_wrapper_owner(
00164 rc_interface_wrapper_base* wrapper) = 0;
00165
00166 private:
00167
00169 state_type& p_state;
00170
00172 unsigned int& p_transaction_count;
00173
00175 wrapper_pool& s_wrapper_pool;
00176
00178 wrapper_handle p_dyn_wrapper_handle;
00179
00181 filter_chain p_dyn_filter_chain;
00182
00184 accessor_base_type* p_first_dyn_filter;
00185
00187 rc_reconfigurable* p_dyn_module;
00188
00190 wrapper_handle p_reserved_wrapper_handle;
00191
00193 rc_interface_wrapper_base* p_exclusive_wrapper;
00194 };
00195
00199 template<class IF>
00200 class rc_abstract_exportal
00201 : public rc_exportal_base,
00202 public rc_abstract_switch<IF>
00203 {
00204 RC_STATIC_ASSERT_VALID_INTERFACE(IF);
00205
00206 private:
00207 typedef rc_abstract_exportal<IF> this_type;
00208 typedef rc_exportal_base base_type;
00209 typedef rc_abstract_switch<IF> switch_parent_type;
00210 typedef rc_switch::state_type state_type;
00211
00212 typedef typename base_type::accessor_base_type accessor_base_type;
00213 typedef typename rc_interface_wrapper<IF>::accessor accessor_b_type;
00214
00215 typedef boost::function<const sc_event& (IF*)> event_getter_type;
00216 typedef std::pair<std::string, event_getter_type> ef_decl_type;
00217 typedef std::vector<ef_decl_type> ef_decl_vector;
00218
00219 typedef internals::exportal::wrapper_pool wrapper_pool;
00220
00221 protected:
00222 typedef rc_exportal_base::wrapper_factory wrapper_factory;
00223
00224 using switch_parent_type::m_state;
00225 using switch_parent_type::m_transaction_count;
00226
00227 public:
00228 typedef IF if_type;
00229 typedef rc_accessor<IF> accessor_type;
00230
00231 private:
00232 class interface_wrapper;
00233
00234 public:
00235
00237 virtual std::string get_switch_kind() const
00238 { return "portal"; }
00239
00241 virtual std::string get_switch_name() const
00242 { return this->name(); }
00243
00245 virtual sc_interface* get_static_interface() const
00246 { return &this->get_static_accessor(); }
00247
00249 sc_export<IF>& static_export();
00250
00252 operator sc_export<IF>&()
00253 { return this->static_export(); }
00254
00256 IF* operator->()
00257 { return this->static_export().operator->(); }
00258
00260 void static_export(sc_port<IF>& port_)
00261 { port_.bind(this->static_export()); }
00262
00264 void bind_static(sc_port<IF>& port_)
00265 { port_.bind(this->static_export()); }
00266
00268 void bind_static(sc_export<IF>& export_)
00269 { export_.bind(this->static_export()); }
00270
00272 void bind_dynamic(sc_export<IF>& export_)
00273 { base_type::bind_dynamic(rc_export_handle(export_)); }
00274
00276 void bind_dynamic(IF& dynamic_if_)
00277 { base_type::bind_dynamic(dynamic_if_); }
00278
00280 rc_interface_wrapper<IF>& bind_exclusively(IF& dynamic_if_);
00281
00283 void dynamic_export(sc_export<IF>& export_)
00284 { base_type::bind_dynamic(export_); }
00285
00286 protected:
00287
00289 explicit rc_abstract_exportal(const sc_module_name& module_name);
00290
00291 virtual void bind_static_object(const rc_object_handle& obj_to_bind);
00292
00293 virtual void bind_dynamic_object(const rc_object_handle& obj_to_bind);
00294
00296 virtual void rc_on_refresh_notify() { }
00297
00299 virtual void register_reconfigurable(
00300 rc_reconfigurable& module, sc_interface& dyn_interface);
00301
00303 virtual void unregister_reconfigurable(rc_reconfigurable& module);
00304
00306 void add_event_forwarder(
00307 event_getter_type event_getter,
00308 const std::string& event_name=NULL);
00309
00311 rc_interface_wrapper<IF>* get_interface_wrapper() const;
00312
00314 IF* get_interface() const;
00315
00317 virtual rc_interface_wrapper_base* create_interface_wrapper(
00318 sc_interface& wrapped_if);
00319
00321 virtual accessor_type* create_accessor() const
00322 { return new accessor_type(); }
00323
00324 virtual void before_end_of_elaboration();
00325
00326 private:
00327
00329 accessor_type& get_static_accessor() const;
00330
00331 private:
00332
00333
00334
00335 virtual accessor_base_type& _rc_get_static_accessor()
00336 { return this->get_static_accessor(); }
00337
00338 virtual bool _rc_check_interface_type(sc_interface* dyn_if) const
00339 { return (dynamic_cast<IF*>(dyn_if) != NULL); }
00340
00341 virtual bool _rc_check_accessor_if_type(
00342 accessor_base_type* accessor) const
00343 { return (dynamic_cast<accessor_b_type*>(accessor) != NULL); }
00344
00350 virtual void _rc_set_interface_wrapper_owner(
00351 rc_interface_wrapper_base* wrapper);
00352
00353 private:
00364 sc_export<IF>* p_static_export;
00365
00374 mutable accessor_type* p_static_accessor;
00375
00377 ef_decl_vector p_ef_decl_vector;
00378
00379 private:
00381 static wrapper_pool s_wrapper_pool;
00382 };
00383
00384 template<class IF>
00385 typename rc_abstract_exportal<IF>::wrapper_pool
00386 rc_abstract_exportal<IF>::s_wrapper_pool;
00387
00391 template<class IF>
00392 class rc_abstract_exportal<IF>::interface_wrapper
00393 : public rc_abstract_interface_wrapper<IF>
00394 {
00395 friend class rc_abstract_exportal<IF>;
00396
00397 private:
00398 typedef rc_abstract_interface_wrapper<IF> base_type;
00399
00400 typedef rc_abstract_exportal<IF> exportal_type;
00401 typedef typename exportal_type::ef_decl_vector ef_decl_vector;
00402
00403 public:
00404 typedef typename base_type::accessor_type accessor_type;
00405
00406 public:
00407 interface_wrapper(IF& wrapped_if, exportal_type& owner_exportal);
00408
00410 bool is_owner(exportal_type& owner_exportal) const
00411 { return (p_exportal == &owner_exportal); }
00412
00414 virtual std::string get_interface_wrapper_name() const
00415 { return p_exportal->name(); }
00416
00417 protected:
00419 void set_owner(exportal_type& owner_exportal)
00420 { p_exportal = &owner_exportal; }
00421
00423 virtual accessor_type* create_accessor() const
00424 { return p_exportal->create_accessor(); }
00425
00427 virtual rc_process_behavior_change begin_access_callback()
00428 { return p_exportal->begin_access_callback(); }
00429
00431 virtual void end_access_callback()
00432 { p_exportal->end_access_callback(); }
00433
00434 private:
00436 exportal_type* p_exportal;
00437 };
00438
00439
00440
00441 inline
00442 rc_process_behavior_change rc_exportal_base::begin_access_callback()
00443 {
00444 ++p_transaction_count;
00445 if (p_dyn_module != NULL) {
00446 p_dyn_module->rc_begin_transaction();
00447 rc_process_handle hproc = rc_get_current_process_handle();
00448 return hproc.behavior_change(false);
00449 } else {
00450 return rc_process_behavior_change();
00451 }
00452 }
00453
00454 inline
00455 void rc_exportal_base::end_access_callback()
00456 {
00457 if (p_transaction_count > 0) {
00458 --p_transaction_count;
00459 }
00460 if (p_dyn_module != NULL) {
00461 p_dyn_module->rc_end_transaction();
00462 }
00463 }
00464
00465
00466
00467 template<class IF>
00468 rc_abstract_exportal<IF>::rc_abstract_exportal(
00469 const sc_module_name& module_name)
00470 : base_type(module_name, m_state, m_transaction_count, s_wrapper_pool),
00471 p_static_export(NULL), p_static_accessor(NULL)
00472 { }
00473
00474 template<class IF>
00475 void rc_abstract_exportal<IF>::bind_static_object(
00476 const rc_object_handle& obj_to_bind)
00477 {
00478 if (obj_to_bind.is_export()) {
00479 sc_export<IF>* export_to_bind =
00480 dynamic_cast<sc_export<IF>*>(*obj_to_bind);
00481 if (export_to_bind != NULL) {
00482 (*export_to_bind).bind(this->static_export());
00483 return;
00484 }
00485 } else if (obj_to_bind.is_port()) {
00486 sc_port<IF>* port_to_bind =
00487 dynamic_cast<sc_port<IF>*>(*obj_to_bind);
00488 if (port_to_bind != NULL) {
00489 (*port_to_bind).bind(this->static_export());
00490 return;
00491 }
00492 }
00493 RC_REPORT_ERROR(RC_ID_SWITCH_BINDING_ERROR_,
00494 "'" << obj_to_bind->name() << "'"
00495 " is incompatible with the static export"
00496 " (in exportal '" << this->name() << "')");
00497 }
00498
00499 template<class IF>
00500 void rc_abstract_exportal<IF>::bind_dynamic_object(
00501 const rc_object_handle& obj_to_bind)
00502 {
00503 if (obj_to_bind.is_export()) {
00504 sc_export<IF>* export_to_bind =
00505 dynamic_cast<sc_export<IF>*>(*obj_to_bind);
00506 if (export_to_bind != NULL) {
00507 this->bind_dynamic((sc_export<IF>&)(*export_to_bind));
00508 return;
00509 }
00510 } else if (obj_to_bind.is_channel()) {
00511 IF* if_to_bind = dynamic_cast<IF*>(*obj_to_bind);
00512 if (if_to_bind != NULL) {
00513 this->bind_dynamic(*if_to_bind);
00514 return;
00515 }
00516 }
00517 RC_REPORT_ERROR(RC_ID_SWITCH_BINDING_ERROR_,
00518 "'" << obj_to_bind->name() << "'"
00519 " is incompatible with the dynamic export"
00520 " (in exportal '" << this->name() << "')");
00521 }
00522
00523 template<class IF>
00524 rc_interface_wrapper<IF>&
00525 rc_abstract_exportal<IF>::bind_exclusively(IF& dynamic_if_)
00526 {
00527 std::auto_ptr<interface_wrapper> wrapper(
00528 new interface_wrapper(dynamic_if_, *this));
00529 base_type::bind_exclusively(*(wrapper.get()));
00530 return *(wrapper.release());
00531 }
00532
00533 template<class IF>
00534 sc_export<IF>& rc_abstract_exportal<IF>::static_export()
00535 {
00536 if (p_static_export == NULL) {
00537 p_static_export = new sc_export<IF>("static_export");
00538
00539 }
00540 if (p_static_export->get_interface() == NULL) {
00541 p_static_export->bind(this->get_static_accessor());
00542 }
00543 return *p_static_export;
00544 }
00545
00546 template<class IF>
00547 void rc_abstract_exportal<IF>::register_reconfigurable(
00548 rc_reconfigurable& module, sc_interface& dyn_if)
00549 {
00550 base_type::register_reconfigurable(module, dyn_if);
00551 switch_parent_type::register_reconfigurable(module, dyn_if);
00552 }
00553
00554 template<class IF>
00555 void rc_abstract_exportal<IF>::unregister_reconfigurable(
00556 rc_reconfigurable& module)
00557 {
00558 base_type::unregister_reconfigurable(module);
00559 switch_parent_type::unregister_reconfigurable(module);
00560 }
00561
00562 template<class IF>
00563 void rc_abstract_exportal<IF>::add_event_forwarder(
00564 event_getter_type event_getter,
00565 const std::string& event_name)
00566 {
00567 std::string _event_name(event_name);
00568 if (_event_name.empty()) {
00569 _event_name = sc_gen_unique_name("event");
00570 }
00571 p_ef_decl_vector.push_back(ef_decl_type(_event_name, event_getter));
00572 }
00573
00574 template<class IF>
00575 rc_interface_wrapper<IF>*
00576 rc_abstract_exportal<IF>::get_interface_wrapper() const
00577 {
00578 return dynamic_cast<rc_interface_wrapper<IF>*>(
00579 base_type::get_interface_wrapper_base());
00580 }
00581
00582 template<class IF>
00583 IF* rc_abstract_exportal<IF>::get_interface() const
00584 {
00585 rc_interface_wrapper_base* wrapper =
00586 base_type::get_interface_wrapper_base();
00587 if (wrapper != NULL) {
00588 return dynamic_cast<IF*>(&wrapper->get_wrapped_interface());
00589 } else {
00590 return NULL;
00591 }
00592 }
00593
00594 template<class IF>
00595 rc_interface_wrapper_base*
00596 rc_abstract_exportal<IF>::create_interface_wrapper(
00597 sc_interface& wrapped_if)
00598 {
00599 IF* wrapped_if_ = dynamic_cast<IF*>(&wrapped_if);
00600 if (wrapped_if_ != NULL) {
00601 return new interface_wrapper(*wrapped_if_, *this);
00602 } else {
00603 return NULL;
00604 }
00605 }
00606
00607 template<class IF>
00608 typename rc_abstract_exportal<IF>::accessor_type&
00609 rc_abstract_exportal<IF>::get_static_accessor() const
00610 {
00611 if (p_static_accessor == NULL) {
00612 p_static_accessor = this->create_accessor();
00613 }
00614 return *p_static_accessor;
00615 }
00616
00617 template<class IF>
00618 void rc_abstract_exportal<IF>::before_end_of_elaboration()
00619 {
00620 base_type::before_end_of_elaboration();
00621
00622
00623 this->static_export();
00624 }
00625
00626 template<class IF>
00627 rc_abstract_exportal<IF>::interface_wrapper::interface_wrapper(
00628 IF& wrapped_if, exportal_type& owner_exportal)
00629 : base_type(wrapped_if), p_exportal(&owner_exportal)
00630 {
00631 for (typename ef_decl_vector::iterator it =
00632 owner_exportal.p_ef_decl_vector.begin();
00633 it != owner_exportal.p_ef_decl_vector.end();
00634 ++it)
00635 {
00636 this->add_event_forwarder(
00637 wrapped_if, it->second, it->first.c_str());
00638 }
00639 }
00640
00641 template<class IF>
00642 void rc_abstract_exportal<IF>::_rc_set_interface_wrapper_owner(
00643 rc_interface_wrapper_base* wrapper)
00644 {
00645 interface_wrapper* wrapper_ =
00646 dynamic_cast<interface_wrapper*>(wrapper);
00647 if (wrapper_ != NULL) {
00648 wrapper_->set_owner(*this);
00649 }
00650 }
00651
00652 }
00653
00654 #endif // RC_ABSTRACT_EXPORTAL_H_
00655
00656
00657
00658