rc_abstract_exportal.h

Go to the documentation of this file.
00001 // vim:set et sts=4 ts=4 tw=75 sw=4 ai ci cin cino=g0,t0:
00002 /*
00003  * Copyright (C) 2007, Technical Computer Science Group,
00004  *                     University of Bonn
00005  *
00006  * This file is part of the ReChannel library.
00007  *
00008  * The ReChannel library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be
00014  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this library; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00021  * Boston, MA 02110-1301, USA.
00022  *
00023  * Authors: Andreas Raabe and Armin Felke. Implementation by Armin Felke.
00024  *          {raabe, felke}@cs.uni-bonn.de
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 /* special callback methods */
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 /* special callback method definitions */
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 /* inline code */
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 /* template code */
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         // (sc_export object will be deleted by SystemC)
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     // ensure existence of static_export and its binding
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 } // namespace ReChannel
00653 
00654 #endif // RC_ABSTRACT_EXPORTAL_H_
00655 //
00656 // $Id: rc_abstract_exportal.h,v 1.20 2008/01/01 13:46:06 felke Exp $
00657 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/communication/exportals/rc_abstract_exportal.h,v $
00658 //

Generated on Tue Jan 1 23:13:30 2008 for ReChannel by  doxygen 1.5.3