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_SWITCH_H_ 00038 #define RC_ABSTRACT_SWITCH_H_ 00039 00040 #include "ReChannel/core/rc_common_header.h" 00041 #include "ReChannel/core/rc_switch.h" 00042 #include "ReChannel/communication/rc_fallback_interface.h" 00043 #include "ReChannel/communication/rc_event_forwarder.h" 00044 00045 namespace ReChannel { 00046 00047 class rc_reconfigurable; 00048 00049 template<class IF> class rc_abstract_switch; 00050 00054 class rc_abstract_switch_b 00055 : virtual public rc_switch 00056 { 00057 template<class IF> friend class rc_abstract_switch; 00058 00059 private: 00060 typedef std::set<void*> set; 00061 typedef std::map<rc_reconfigurable*, void*> module_void_map; 00062 public: 00063 typedef rc_switch::state_type state_type; 00064 00065 private: 00066 rc_abstract_switch_b(); 00067 00068 public: 00069 virtual state_type get_switch_state() const 00070 { return m_state; } 00071 00072 virtual unsigned int get_transaction_count() const 00073 { return m_transaction_count; } 00074 00075 virtual bool is_registered(const rc_reconfigurable& module) const 00076 { 00077 return (p_mod_if_map.find(const_cast<rc_reconfigurable*>(&module)) 00078 != p_mod_if_map.end()); 00079 } 00080 00081 virtual bool is_locked() const 00082 { return (p_lock_owner != NULL); } 00083 00084 virtual std::string get_switch_kind() const 00085 { return "switch"; } 00086 00087 virtual std::string get_switch_name() const 00088 { return "(unknown)"; }; 00089 00090 virtual ~rc_abstract_switch_b(); 00091 00092 protected: 00093 00094 virtual void register_reconfigurable( 00095 rc_reconfigurable& module, sc_interface& dyn_if); 00096 00097 virtual void unregister_reconfigurable(rc_reconfigurable& module); 00098 00099 virtual bool is_lock_owner(const rc_reconfigurable& reconf) const 00100 { return (p_lock_owner == &reconf); } 00101 00102 virtual bool set_locked(rc_reconfigurable& lock_owner, bool lock); 00103 00104 private: 00105 00106 inline void* find_registered_if(rc_reconfigurable* module) const; 00107 00108 inline bool is_registered(void* dyn_if) const; 00109 00110 private: 00111 00112 /* special (untyped!!!) callback methods */ 00113 00114 virtual void* _rc_dynamic_cast(sc_interface* dyn_if) const = 0; 00115 00116 virtual const char* _rc_get_if_type() const = 0; 00117 00118 protected: 00119 state_type m_state; 00120 unsigned int m_transaction_count; 00121 00122 private: 00123 00124 /* for internal use only! */ 00125 00126 rc_reconfigurable* p_lock_owner; 00127 set p_interface_set; 00128 module_void_map p_mod_if_map; 00129 00130 private: 00131 // disabled 00132 rc_abstract_switch_b(const rc_abstract_switch_b& orig); 00133 rc_abstract_switch_b& operator=(const rc_abstract_switch_b& orig); 00134 }; 00135 00139 template<class IF> 00140 class rc_abstract_switch 00141 : public rc_abstract_switch_b 00142 { 00143 RC_STATIC_ASSERT_VALID_INTERFACE(IF); 00144 00145 private: 00146 typedef rc_abstract_switch_b base_type; 00147 00148 protected: 00149 rc_abstract_switch() { } 00150 00151 public: 00152 00153 virtual bool is_registered(const sc_interface& dyn_if) const; 00154 00155 protected: 00156 00157 inline IF* get_registered_if(rc_reconfigurable& module) const; 00158 00159 virtual sc_interface* get_registered_interface( 00160 rc_reconfigurable& module) const 00161 { return get_registered_if(module); } 00162 00163 private: 00164 00165 /* for internal use only */ 00166 00167 virtual void* _rc_dynamic_cast(sc_interface* dyn_if) const; 00168 00169 virtual const char* _rc_get_if_type() const; 00170 00171 private: 00172 // disabled 00173 rc_abstract_switch(const rc_abstract_switch& orig); 00174 rc_abstract_switch& operator=(const rc_abstract_switch& orig); 00175 }; 00176 00177 /* inline code */ 00178 00179 inline 00180 void* rc_abstract_switch_b::find_registered_if( 00181 rc_reconfigurable* module) const 00182 { 00183 module_void_map::const_iterator it = p_mod_if_map.find(module); 00184 return (it != p_mod_if_map.end() ? it->second : NULL); 00185 } 00186 00187 inline 00188 bool rc_abstract_switch_b::is_registered(void* dyn_if) const 00189 { 00190 return (p_interface_set.find(dyn_if) != p_interface_set.end()); 00191 } 00192 00193 /* template code */ 00194 00195 template<class IF> 00196 inline 00197 bool rc_abstract_switch<IF>::is_registered( 00198 const sc_interface& dyn_if) const 00199 { 00200 return base_type::is_registered( 00201 dynamic_cast<IF*>(const_cast<sc_interface*>(&dyn_if))); 00202 } 00203 00204 template<class IF> 00205 inline 00206 IF* rc_abstract_switch<IF>::get_registered_if( 00207 rc_reconfigurable& module) const 00208 { 00209 return reinterpret_cast<IF*>(base_type::find_registered_if(&module)); 00210 } 00211 00212 template<class IF> 00213 void* rc_abstract_switch<IF>::_rc_dynamic_cast(sc_interface* dyn_if) const 00214 { 00215 return dynamic_cast<IF*>(dyn_if); 00216 } 00217 00218 template<class IF> 00219 const char* rc_abstract_switch<IF>::_rc_get_if_type() const 00220 { 00221 return typeid(IF).name(); 00222 } 00223 00224 } // namespace ReChannel 00225 00226 /* macros to declare callback methods for opening and closing switches */ 00227 00228 #define RC_ON_OPEN() \ 00229 virtual void rc_on_open() 00230 00231 #define RC_ON_CLOSE() \ 00232 virtual void rc_on_close() 00233 00234 #define RC_ON_UNDEF() \ 00235 virtual void rc_on_undef() 00236 00237 #define RC_ON_REFRESH_NOTIFY() \ 00238 virtual void rc_on_refresh_notify() 00239 00240 #endif // RC_ABSTRACT_SWITCH_H_ 00241 00242 // 00243 // $Id: rc_abstract_switch.h,v 1.10 2007/12/20 20:25:55 felke Exp $ 00244 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/communication/rc_abstract_switch.h,v $ 00245 //