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_RECONFIGURABLE_H_
00038 #define RC_RECONFIGURABLE_H_
00039
00040 #include <boost/multi_index_container.hpp>
00041 #include <boost/multi_index/ordered_index.hpp>
00042 #include <boost/multi_index/member.hpp>
00043
00044 #include "ReChannel/core/rc_common_header.h"
00045 #include "ReChannel/core/rc_switch.h"
00046 #include "ReChannel/core/rc_resettable.h"
00047 #include "ReChannel/core/rc_process.h"
00048 #include "ReChannel/core/rc_reconfigurable_set.h"
00049 #include "ReChannel/core/rc_portmap.h"
00050 #include "ReChannel/core/rc_switch_connector.h"
00051
00052 #include "ReChannel/util/rc_driver_object.h"
00053 #include "ReChannel/util/rc_mutex_object.h"
00054 #include "ReChannel/util/rc_delta_sync_object.h"
00055 #include "ReChannel/util/rc_hash_map.h"
00056 #include "ReChannel/util/rc_object_handle.h"
00057 #include "ReChannel/util/rc_port_handle.h"
00058 #include "ReChannel/util/rc_export_handle.h"
00059
00060 namespace ReChannel {
00061
00062 class rc_control;
00063 class rc_transaction_counter;
00064
00065
00066 class rc_reconfigurable;
00067 rc_reconfigurable* rc_get_reconfigurable_context();
00068 rc_reconfigurable* rc_get_reconfigurable_context(sc_object* start_search);
00069
00070 namespace internals {
00071 namespace reconfigurable {
00072
00081 class temporary_object : public sc_object {};
00082
00100 class begin_construction
00101 {
00102 friend void end_construction(begin_construction& constr);
00103 friend rc_reconfigurable* ::ReChannel::rc_get_reconfigurable_context();
00104 friend rc_reconfigurable* ::ReChannel::rc_get_reconfigurable_context(
00105 sc_object* start_search);
00106
00107 protected:
00114 explicit begin_construction(rc_reconfigurable& reconf);
00115
00124 void finish();
00125
00136 void finish(sc_object& reconf);
00137
00143 ~begin_construction()
00144 { finish(); }
00145
00146 private:
00151 rc_reconfigurable* p_previous;
00155 bool p_finished;
00156
00157 private:
00162 static rc_reconfigurable* s_current;
00163
00164 private:
00165
00167 begin_construction(const begin_construction& reconf);
00169 begin_construction& operator=(const begin_construction& reconf);
00170 };
00171
00181 inline void end_construction(begin_construction& constr)
00182 { constr.finish(); }
00183
00184 }
00185 }
00186
00207 class rc_reconfigurable
00208 {
00212 friend class rc_control;
00213
00214 friend class internals::reconfigurable::begin_construction;
00215
00219 friend class rc_transaction;
00220
00225 friend class rc_transaction_counter;
00226
00227 public:
00232 typedef rc_switch_connector_base switch_conn_type;
00233
00238 typedef rc_switch::filter_chain filter_chain;
00239
00240 private:
00241 typedef std::pair<rc_switch*, rc_object_handle> switch_commobj_pair;
00242
00247 typedef boost::multi_index_container<
00248 switch_commobj_pair,
00249 boost::multi_index::indexed_by<
00250 boost::multi_index::ordered_unique<
00251 BOOST_MULTI_INDEX_MEMBER(
00252 switch_commobj_pair, rc_switch*, first)
00253 >,
00254 boost::multi_index::ordered_non_unique<
00255 BOOST_MULTI_INDEX_MEMBER(
00256 switch_commobj_pair, rc_object_handle, second)
00257 >
00258 >
00259 > switch_commobj_map;
00260
00264 typedef switch_commobj_map::nth_index<0>::type switch_commobj_index;
00265
00269 typedef switch_commobj_map::nth_index<1>::type commobj_switch_index;
00270
00274 typedef std::pair<
00275 switch_commobj_index::iterator,
00276 switch_commobj_index::iterator> switch_commobj_range;
00277
00281 typedef std::pair<
00282 commobj_switch_index::iterator,
00283 commobj_switch_index::iterator> commobj_switch_range;
00284
00288 typedef std::set<rc_interface_filter*> filter_set;
00289
00293 typedef std::map<rc_object_handle, filter_chain> commobj_filters_map;
00294
00298 typedef std::set<rc_resettable*> resettable_set;
00299
00303 typedef std::vector<rc_portmap_base*> portmap_vector;
00304
00305 public:
00309 enum state_type { UNLOADED=0, INACTIVE, ACTIVE };
00310
00314 enum { STATE_COUNT=3 };
00315
00319 enum action_type { UNLOAD=0, LOAD, ACTIVATE, DEACTIVATE };
00320
00324 enum { ACTION_COUNT=4 };
00325
00326 protected:
00327
00333 rc_reconfigurable(sc_object* this_=NULL);
00334
00335 public:
00336
00343 std::string rc_get_name() const;
00344
00350 const sc_object* rc_get_object() const;
00351
00357 sc_object* rc_get_object();
00358
00362 inline state_type rc_get_state() const
00363 { return p_state; }
00364
00369 inline bool rc_is_state_changing() const
00370 { return (p_state != p_next_state); }
00371
00375 inline state_type rc_get_next_state() const
00376 { return p_next_state; }
00377
00381 inline bool rc_is_loaded() const
00382 { return (p_state != UNLOADED); }
00383
00387 inline bool rc_is_active() const
00388 { return (p_state == ACTIVE); }
00389
00396 inline int rc_get_transaction_count() const
00397 { return p_transaction_count; }
00398
00404 void bind(rc_switch_connector_base& switch_connector);
00405
00414 void rc_register_switch(
00415 rc_switch& switch_obj, const rc_object_handle& bound_obj);
00416
00420 bool rc_is_registered(rc_switch& switch_obj) const;
00421
00430 void rc_register_resettable(rc_resettable& resettable);
00431
00435 bool rc_is_registered(rc_resettable& resettable) const;
00436
00446 inline void rc_begin_transaction()
00447 { ++p_transaction_count; }
00448
00458 inline void rc_end_transaction();
00459
00467 void rc_possible_deactivation();
00468
00480 void rc_possible_deactivation_delta();
00481
00485 inline bool rc_is_deactivation_requested() const
00486 { return (p_next_state == INACTIVE && p_state == ACTIVE); }
00487
00494 void rc_set_delay(action_type a, sc_time t);
00495
00499 inline sc_time rc_get_delay(action_type a) const
00500 { return p_action_delays[a]; }
00501
00505 inline void rc_set_default_delay(action_type a, sc_time t)
00506 { p_action_default_delays[a] = t; }
00507
00516 inline sc_time rc_get_default_delay(action_type a) const
00517 { return p_action_default_delays[a]; }
00518
00524 inline operator const rc_reconfigurable_set&() const
00525 { return p_self_set; }
00526
00535 inline const rc_process_control& rc_get_process_control() const
00536 { return p_pctrl; }
00537
00544 inline switch_conn_type* rc_get_current_switch_connector() const
00545 { return p_curr_switch_conn; }
00546
00550 virtual ~rc_reconfigurable();
00551
00552 protected:
00553
00562 virtual void rc_on_load() {}
00563
00572 virtual void rc_on_activate() {}
00573
00582 virtual void rc_on_deactivate() {}
00583
00592 virtual void rc_on_unload() {}
00593
00602 void rc_add_portmap(rc_portmap_base& portmap);
00603
00607 void rc_clear_portmaps();
00608
00614 bool rc_is_compatible(const rc_portmap_base& portmap) const
00615 { return (this->_rc_is_compatible(portmap) > -1); }
00616
00623 void rc_add_filter(
00624 const rc_object_handle& commobj_, rc_interface_filter& filter_);
00625
00630 int rc_get_filter_count(const rc_object_handle& commobj_) const;
00631
00636 filter_chain rc_get_filter_chain(
00637 const rc_object_handle& commobj_) const;
00638
00642 bool rc_has_filter(rc_interface_filter& filter_) const;
00643
00648 void rc_refresh_notify(const rc_object_handle& commobj_);
00649
00654 void rc_refresh_notify_all();
00655
00656 private:
00657
00662 static void get_all_reconfigurables(
00663 std::vector<rc_reconfigurable*>& copy_dest)
00664 { copy_dest = s_reconfigurables; }
00665
00666 private:
00670 inline rc_control* get_control() const
00671 { return p_control; }
00672
00676 void set_control(rc_control* control)
00677 { p_control = control; }
00678
00688 void start_of_simulation();
00689
00695 void reconfigure(state_type new_state);
00696
00701 void change_switch_state(rc_switch::state_type new_state);
00702
00707 void move(switch_conn_type& target);
00708
00712 inline bool has_lock() const
00713 { return p_mutex.has_lock(); }
00714
00718 inline bool is_locked() const
00719 { return p_mutex.is_locked(); }
00720
00724 inline const sc_event& get_lock_release_event() const
00725 { return p_mutex.get_lock_release_event(); }
00726
00731 inline bool trylock()
00732 { return p_mutex.trylock(); }
00733
00737 inline void lock()
00738 { p_mutex.lock(); }
00739
00743 inline bool lock(sc_time timeout)
00744 { return p_mutex.lock(timeout); }
00745
00750 bool unlock();
00751
00758 bool share_lock(sc_process_handle proc);
00759
00763 bool reset_lock_share();
00764
00768 inline bool has_lock_share() const
00769 { return (p_lock_share == sc_get_current_process_handle()); }
00770
00775 bool lock_switches(bool report_error=false);
00776
00782 void unlock_switches();
00783
00789 void reset_transaction_count();
00790
00794 rc_portmap_base& get_portmap(int index);
00795
00799 int get_portmap_count() const
00800 { return p_portmap_vector.size(); }
00801
00802 private:
00803
00804
00805
00809 void _rc_set_sc_object(sc_object& reconf);
00810
00817 void _rc_delta_sync_state_change(rc_delta_sync_object& delta_sync);
00818
00822 void _rc_unload();
00823
00827 void _rc_load();
00828
00832 void _rc_activate();
00833
00837 void _rc_deactivate();
00838
00842 void _rc_reset();
00843
00847 int _rc_is_compatible(const rc_portmap_base& portmap) const;
00848
00852 rc_portmap_base* _rc_get_compatible_portmap(
00853 const rc_switch_connector_base& switch_conn) const;
00854
00855 private:
00859 static std::vector<rc_reconfigurable*> s_reconfigurables;
00860
00861 private:
00867 mutable sc_object* p_sc_object;
00871 mutable bool p_is_no_sc_object;
00872
00876 state_type p_state;
00883 state_type p_next_state;
00889 int p_transaction_count;
00890
00897 rc_process_control p_pctrl;
00901 rc_delta_sync_object p_delta_sync;
00902
00903 switch_commobj_map p_switch_commobj_map;
00904 switch_commobj_index& p_switch_commobj_index;
00905 commobj_switch_index& p_commobj_switch_index;
00906
00907 filter_set p_filter_set;
00908 commobj_filters_map p_commobj_filters_map;
00909
00910 rc_control* p_control;
00911 rc_reconfigurable_set p_self_set;
00912 rc_mutex_object p_mutex;
00913 sc_process_handle p_lock_share;
00914 sc_time p_action_default_delays[ACTION_COUNT];
00915 sc_time p_action_delays[ACTION_COUNT];
00916
00917 portmap_vector p_portmap_vector;
00918 switch_conn_type* p_curr_switch_conn;
00919
00920 resettable_set p_resettable_set;
00921 };
00922
00941 class rc_transaction
00942 {
00943 public:
00948 inline explicit rc_transaction(rc_reconfigurable* reconf);
00953 inline void begin();
00959 inline void end();
00963 inline bool has_ended() const
00964 { return p_has_ended; }
00968 ~rc_transaction();
00969 private:
00970
00972 rc_transaction(const rc_transaction& orig);
00974 rc_transaction& operator=(const rc_transaction& orig);
00975 private:
00979 rc_reconfigurable* reconf;
00983 bool p_has_ended;
00984 };
00985
00986
00987
00988 inline void rc_reconfigurable::rc_end_transaction()
00989 {
00990 if (p_transaction_count > 1) {
00991 --p_transaction_count;
00992 } else {
00993 this->reset_transaction_count();
00994 }
00995 }
00996
00997 inline rc_transaction::rc_transaction(rc_reconfigurable* reconf)
00998 : reconf(reconf), p_has_ended(false)
00999 {
01000 if (reconf != NULL) {
01001 reconf->rc_begin_transaction();
01002 }
01003
01004 }
01005
01006 inline void rc_transaction::begin()
01007 {
01008 if (p_has_ended && reconf != NULL) {
01009 reconf->rc_begin_transaction();
01010 }
01011
01012 p_has_ended = false;
01013 }
01014
01015 inline void rc_transaction::end()
01016 {
01017 if (!p_has_ended && reconf != NULL) {
01018 reconf->rc_end_transaction();
01019 reconf->rc_possible_deactivation();
01020 }
01021
01022 p_has_ended = true;
01023 }
01024
01025
01026
01042 extern rc_reconfigurable* rc_get_reconfigurable_context();
01043
01060 extern rc_reconfigurable* rc_get_reconfigurable_context(
01061 sc_object* start_search);
01062
01071 extern const rc_reconfigurable* rc_register_resettable(
01072 rc_resettable& resettable, sc_object* search_start);
01073
01074 }
01075
01080 #define RC_LOAD rc_reconfigurable::LOAD
01081
01085 #define RC_ACTIVATE rc_reconfigurable::ACTIVATE
01086
01090 #define RC_DEACTIVATE rc_reconfigurable::DEACTIVATE
01091
01095 #define RC_UNLOAD rc_reconfigurable::UNLOAD
01096
01101 #define RC_ACTIVE rc_reconfigurable::ACTIVE
01102
01106 #define RC_INACTIVE rc_reconfigurable::INACTIVE
01107
01111 #define RC_UNLOADED rc_reconfigurable::UNLOADED
01112
01129 #define RC_ON_LOAD() \
01130 virtual void rc_on_load()
01131
01147 #define RC_ON_ACTIVATE() \
01148 virtual void rc_on_activate()
01149
01165 #define RC_ON_DEACTIVATE() \
01166 virtual void rc_on_deactivate()
01167
01183 #define RC_ON_UNLOAD() \
01184 virtual void rc_on_unload()
01185
01186 #endif //RC_RECONFIGURABLE_H_
01187
01188
01189
01190
01191