00001 /***************************************************************************** 00002 00003 The following code is derived, directly or indirectly, from the SystemC 00004 source code Copyright (c) 1996-2006 by all Contributors. 00005 All Rights reserved. 00006 00007 The contents of this file are subject to the restrictions and limitations 00008 set forth in the SystemC Open Source License Version 2.4 (the "License"); 00009 You may not use this file except in compliance with such restrictions and 00010 limitations. You may obtain instructions on how to receive a copy of the 00011 License at http://www.systemc.org/. Software distributed by Contributors 00012 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 00013 ANY KIND, either express or implied. See the License for the specific 00014 language governing rights and limitations under the License. 00015 00016 *****************************************************************************/ 00017 00018 /***************************************************************************** 00019 00020 sc_event_finder.h -- 00021 00022 Original Author: Martin Janssen, Synopsys, Inc. 00023 Stan Y. Liao, Synopsys, Inc., 2001-05-21 00024 00025 *****************************************************************************/ 00026 00027 /***************************************************************************** 00028 00029 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 00030 changes you are making here. 00031 00032 Name, Affiliation, Date: 00033 Description of Modification: 00034 00035 *****************************************************************************/ 00036 //$Log: sc_event_finder.h,v $ 00037 //Revision 1.1.1.1 2006/12/15 20:31:35 acg 00038 //SystemC 2.2 00039 // 00040 //Revision 1.4 2006/02/02 23:42:37 acg 00041 // Andy Goodrich: implemented a much better fix to the sc_event_finder 00042 // proliferation problem. This new version allocates only a single event 00043 // finder for each port for each type of event, e.g., pos(), neg(), and 00044 // value_change(). The event finder persists as long as the port does, 00045 // which is what the LRM dictates. Because only a single instance is 00046 // allocated for each event type per port there is not a potential 00047 // explosion of storage as was true in the 2.0.1/2.1 versions. 00048 // 00049 //Revision 1.3 2006/02/02 20:43:09 acg 00050 // Andy Goodrich: Added an existence linked list to sc_event_finder so that 00051 // the dynamically allocated instances can be freed after port binding 00052 // completes. This replaces the individual deletions in ~sc_bind_ef, as these 00053 // caused an exception if an sc_event_finder instance was used more than 00054 // once, due to a double freeing of the instance. 00055 // 00056 //Revision 1.2 2006/01/03 23:18:26 acg 00057 //Changed copyright to include 2006. 00058 // 00059 //Revision 1.1.1.1 2005/12/19 23:16:43 acg 00060 //First check in of SystemC 2.1 into its own archive. 00061 // 00062 //Revision 1.10 2005/09/15 23:01:51 acg 00063 //Added std:: prefix to appropriate methods and types to get around 00064 //issues with the Edison Front End. 00065 // 00066 //Revision 1.9 2005/06/10 22:43:55 acg 00067 //Added CVS change log annotation. 00068 // 00069 00070 #ifndef SC_EVENT_FINDER 00071 #define SC_EVENT_FINDER 00072 00073 00074 #include "sysc/communication/sc_port.h" 00075 00076 namespace sc_core { 00077 00078 // ---------------------------------------------------------------------------- 00079 // CLASS : sc_event_finder 00080 // 00081 // Event finder base class. 00082 // ---------------------------------------------------------------------------- 00083 00084 class sc_event_finder 00085 { 00086 friend class sc_simcontext; 00087 00088 public: 00089 00090 const sc_port_base& port() const 00091 { return m_port; } 00092 00093 // destructor (does nothing) 00094 virtual ~sc_event_finder(); 00095 00096 virtual const sc_event& find_event( sc_interface* if_p = 0 ) const = 0; 00097 00098 protected: 00099 00100 // constructor 00101 sc_event_finder( const sc_port_base& ); 00102 00103 // error reporting 00104 void report_error( const char* id, const char* add_msg = 0 ) const; 00105 00106 00107 private: 00108 const sc_port_base& m_port; // port providing the event. 00109 00110 private: 00111 00112 // disabled 00113 sc_event_finder(); 00114 sc_event_finder( const sc_event_finder& ); 00115 sc_event_finder& operator = ( const sc_event_finder& ); 00116 }; 00117 00118 00119 // ---------------------------------------------------------------------------- 00120 // CLASS : sc_event_finder_t<IF> 00121 // 00122 // Interface specific event finder class. 00123 // ---------------------------------------------------------------------------- 00124 00125 template <class IF> 00126 class sc_event_finder_t 00127 : public sc_event_finder 00128 { 00129 public: 00130 00131 // constructor 00132 00133 sc_event_finder_t( const sc_port_base& port_, 00134 const sc_event& (IF::*event_method_) () const ) 00135 : sc_event_finder( port_ ), m_event_method( event_method_ ) 00136 {} 00137 00138 // destructor (does nothing) 00139 00140 virtual ~sc_event_finder_t() 00141 {} 00142 00143 virtual const sc_event& find_event( sc_interface* if_p = 0 ) const; 00144 00145 private: 00146 00147 const sc_event& (IF::*m_event_method) () const; 00148 00149 private: 00150 00151 // disabled 00152 sc_event_finder_t(); 00153 sc_event_finder_t( const sc_event_finder_t<IF>& ); 00154 sc_event_finder_t<IF>& operator = ( const sc_event_finder_t<IF>& ); 00155 }; 00156 00157 00158 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00159 00160 template <class IF> 00161 inline 00162 const sc_event& 00163 sc_event_finder_t<IF>::find_event( sc_interface* if_p ) const 00164 { 00165 const IF* iface = ( if_p ) ? DCAST<const IF*>( if_p ) : 00166 DCAST<const IF*>( port().get_interface() ); 00167 if( iface == 0 ) { 00168 report_error( SC_ID_FIND_EVENT_, "port is not bound" ); 00169 } 00170 return (CCAST<IF*>( iface )->*m_event_method) (); 00171 } 00172 00173 } // namespace sc_core 00174 00175 #endif 00176 00177 // Taf!