00001 /***************************************************************************** 00002 00003 The following code is derived, directly or indirectly, from the SystemC 00004 source code Copyright (c) 1996-2014 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 (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.accellera.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_export.h -- Base classes of all export classes. 00021 00022 Original Author: Andy Goodrich, Forte Design Systems 00023 Bishnupriya Bhattacharya, Cadence Design Systems 00024 00025 CHANGE LOG IS AT THE END OF THE FILE 00026 *****************************************************************************/ 00027 00028 #ifndef SC_EXPORT_H 00029 #define SC_EXPORT_H 00030 #include <typeinfo> 00031 00032 #include "sysc/communication/sc_communication_ids.h" 00033 #include "sysc/communication/sc_interface.h" 00034 #include "sysc/kernel/sc_object.h" 00035 00036 #if ! defined( SC_DISABLE_VIRTUAL_BIND ) 00037 # define SC_VIRTUAL_ virtual 00038 #else 00039 # define SC_VIRTUAL_ /* non-virtual */ 00040 #endif 00041 00042 namespace sc_core { 00043 00044 /**************************************************************************/ 00050 class sc_export_base : public sc_object 00051 { 00052 friend class sc_export_registry; 00053 public: 00054 00055 // typedefs 00056 00057 typedef sc_export_base this_type; 00058 00059 public: 00060 00061 virtual sc_interface* get_interface() = 0; 00062 virtual const sc_interface* get_interface() const = 0; 00063 00064 protected: 00065 00066 // constructors 00067 00068 sc_export_base(); 00069 sc_export_base(const char* name); 00070 00071 // destructor 00072 00073 virtual ~sc_export_base(); 00074 00075 protected: 00076 00077 // called when construction is done 00078 virtual void before_end_of_elaboration(); 00079 00080 // called when elaboration is done (does nothing by default) 00081 virtual void end_of_elaboration(); 00082 00083 // called before simulation starts (does nothing by default) 00084 virtual void start_of_simulation(); 00085 00086 // called after simulation ends (does nothing) 00087 virtual void end_of_simulation(); 00088 00089 virtual const char* if_typename() const = 0; 00090 00091 // error reporting 00092 void report_error( const char* id, const char* add_msg = 0) const; 00093 00094 private: 00095 00096 void construction_done(); 00097 void elaboration_done(); 00098 void start_simulation(); 00099 void simulation_done(); 00100 00101 // disabled 00102 sc_export_base(const this_type&); 00103 this_type& operator = (const this_type& ); 00104 00105 }; 00106 00107 /**************************************************************************/ 00114 template<class IF> 00115 class sc_export : public sc_export_base 00116 { 00117 typedef sc_export<IF> this_type; 00118 00119 public: // constructors: 00120 sc_export() : sc_export_base() 00121 { 00122 m_interface_p = 0; 00123 } 00124 00125 explicit sc_export( const char* name_ ) : sc_export_base(name_) 00126 { 00127 m_interface_p = 0; 00128 } 00129 00130 public: // destructor: 00131 virtual ~sc_export() 00132 { 00133 } 00134 00135 public: // interface access: 00136 00137 virtual sc_interface* get_interface() 00138 { 00139 return m_interface_p; 00140 } 00141 00142 virtual const sc_interface* get_interface() const 00143 { 00144 return m_interface_p; 00145 } 00146 00147 const IF* operator -> () const { 00148 if ( m_interface_p == 0 ) 00149 { 00150 SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name()); 00151 } 00152 return m_interface_p; 00153 } 00154 00155 IF* operator -> () { 00156 if ( m_interface_p == 0 ) 00157 { 00158 SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name()); 00159 } 00160 return m_interface_p; 00161 } 00162 00163 operator IF& () 00164 { 00165 if ( m_interface_p == 0 ) 00166 { 00167 SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name()); 00168 } 00169 return *m_interface_p; 00170 } 00171 operator const IF&() const 00172 { return *const_cast<this_type*>(this); } 00173 00174 00175 public: // binding: 00176 SC_VIRTUAL_ void bind( IF& interface_ ) 00177 { 00178 if ( m_interface_p ) 00179 { 00180 SC_REPORT_ERROR(SC_ID_SC_EXPORT_ALREADY_BOUND_,name()); 00181 } 00182 else 00183 { 00184 m_interface_p = &interface_; 00185 } 00186 } 00187 00188 void operator () ( IF& interface_ ) 00189 { 00190 this->bind(interface_); 00191 } 00192 00193 public: // identification: 00194 virtual const char* kind() const { return "sc_export"; } 00195 00196 protected: 00197 const char* if_typename() const { 00198 return typeid( IF ).name(); 00199 } 00200 00201 private: // disabled 00202 sc_export( const this_type& ); 00203 this_type& operator = ( const this_type& ); 00204 00205 protected: // data fields: 00206 IF* m_interface_p; // Interface this port provides. 00207 }; 00208 00209 /**************************************************************************/ 00217 class sc_export_registry 00218 { 00219 friend class sc_simcontext; 00220 00221 public: 00222 00223 void insert( sc_export_base* ); 00224 void remove( sc_export_base* ); 00225 00226 int size() const 00227 { return m_export_vec.size(); } 00228 00229 private: 00230 00231 // constructor 00232 explicit sc_export_registry( sc_simcontext& simc_ ); 00233 00234 // destructor 00235 ~sc_export_registry(); 00236 00237 // called when construction is done 00238 bool construction_done(); 00239 00240 // called when elaboration is done 00241 void elaboration_done(); 00242 00243 // called before simulation starts 00244 void start_simulation(); 00245 00246 // called after simulation ends 00247 void simulation_done(); 00248 00249 private: 00250 00251 int m_construction_done; 00252 std::vector<sc_export_base*> m_export_vec; 00253 sc_simcontext* m_simc; 00254 00255 private: 00256 00257 // disabled 00258 sc_export_registry(); 00259 sc_export_registry( const sc_export_registry& ); 00260 sc_export_registry& operator = ( const sc_export_registry& ); 00261 }; 00262 00263 } // namespace sc_core 00264 00265 #undef SC_VIRTUAL_ 00266 00267 // $Log: sc_export.h,v $ 00268 // Revision 1.7 2011/08/26 20:45:40 acg 00269 // Andy Goodrich: moved the modification log to the end of the file to 00270 // eliminate source line number skew when check-ins are done. 00271 // 00272 // Revision 1.6 2011/05/09 04:07:37 acg 00273 // Philipp A. Hartmann: 00274 // (1) Restore hierarchy in all phase callbacks. 00275 // (2) Ensure calls to before_end_of_elaboration. 00276 // 00277 // Revision 1.5 2011/04/02 00:02:14 acg 00278 // Philipp A. Hartmann: add const overload for sc_export::operator IF& 00279 // 00280 // Revision 1.4 2011/02/18 20:23:45 acg 00281 // Andy Goodrich: Copyright update. 00282 // 00283 // Revision 1.3 2011/02/14 17:50:16 acg 00284 // Andy Goodrich: testing for sc_port and sc_export instantiations during 00285 // end of elaboration and issuing appropriate error messages. 00286 // 00287 // Revision 1.2 2011/01/20 16:52:15 acg 00288 // Andy Goodrich: changes for IEEE 1666 2011. 00289 // 00290 // Revision 1.1.1.1 2006/12/15 20:20:04 acg 00291 // SystemC 2.3 00292 // 00293 // Revision 1.3 2006/01/13 18:47:42 acg 00294 // Added $Log command so that CVS comments are reproduced in the source. 00295 // 00296 00297 #endif 00298 00299 // Taf!