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_signal_rv.h -- The resolved vector signal class. 00021 00022 Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21 00023 00024 CHANGE LOG IS AT THE END OF THE FILE 00025 *****************************************************************************/ 00026 00027 #ifndef SC_SIGNAL_RV_H 00028 #define SC_SIGNAL_RV_H 00029 00030 #include "sysc/communication/sc_signal.h" 00031 #include "sysc/datatypes/bit/sc_lv.h" 00032 00033 namespace sc_core { 00034 00035 class sc_process_b; 00036 00037 00038 /**************************************************************************/ 00044 extern const sc_dt::sc_logic_value_t sc_logic_resolution_tbl[4][4]; 00045 00046 00047 template <int W> 00048 class sc_lv_resolve 00049 { 00050 public: 00051 00052 // resolves sc_dt::sc_lv<W> values and returns the resolved value 00053 static void resolve(sc_dt::sc_lv<W>&, const std::vector<sc_dt::sc_lv<W>*>&); 00054 }; 00055 00056 00057 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00058 00059 // resolves sc_dt::sc_lv<W> values and returns the resolved value 00060 00061 template <int W> 00062 inline 00063 void 00064 sc_lv_resolve<W>::resolve( sc_dt::sc_lv<W>& result_, 00065 const std::vector<sc_dt::sc_lv<W>*>& values_ ) 00066 { 00067 int sz = values_.size(); 00068 00069 assert( sz != 0 ); 00070 00071 if( sz == 1 ) { 00072 result_ = *values_[0]; 00073 return; 00074 } 00075 00076 for( int j = result_.length() - 1; j >= 0; -- j ) { 00077 sc_dt::sc_logic_value_t res = (*values_[0])[j].value(); 00078 for( int i = sz - 1; i > 0 && res != 3; -- i ) { 00079 res = sc_logic_resolution_tbl[res][(*values_[i])[j].value()]; 00080 } 00081 result_[j] = res; 00082 } 00083 } 00084 00085 00086 /**************************************************************************/ 00092 template <int W> 00093 class sc_signal_rv 00094 : public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS> 00095 { 00096 public: 00097 00098 // typedefs 00099 00100 typedef sc_signal_rv<W> this_type; 00101 typedef sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS> base_type; 00102 typedef sc_dt::sc_lv<W> data_type; 00103 00104 public: 00105 00106 // constructors 00107 00108 sc_signal_rv() 00109 : base_type( sc_gen_unique_name( "signal_rv" ) ) 00110 {} 00111 00112 explicit sc_signal_rv( const char* name_ ) 00113 : base_type( name_ ) 00114 {} 00115 00116 00117 // destructor 00118 virtual ~sc_signal_rv(); 00119 00120 00121 // interface methods 00122 00123 virtual void register_port( sc_port_base&, const char* ) 00124 {} 00125 00126 00127 // write the new value 00128 virtual void write( const data_type& ); 00129 00130 00131 // other methods 00132 00133 this_type& operator = ( const data_type& a ) 00134 { write( a ); return *this; } 00135 00136 this_type& operator = ( const this_type& a ) 00137 { write( a.read() ); return *this; } 00138 00139 virtual const char* kind() const 00140 { return "sc_signal_rv"; } 00141 00142 protected: 00143 00144 virtual void update(); 00145 00146 protected: 00147 00148 std::vector<sc_process_b*> m_proc_vec; // processes writing this signal 00149 std::vector<data_type*> m_val_vec; // new values written this signal 00150 00151 private: 00152 00153 // disabled 00154 sc_signal_rv( const this_type& ); 00155 }; 00156 00157 00158 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 00159 00160 00161 // destructor 00162 00163 template <int W> 00164 inline 00165 sc_signal_rv<W>::~sc_signal_rv() 00166 { 00167 for( int i = m_val_vec.size() - 1; i >= 0; -- i ) { 00168 delete m_val_vec[i]; 00169 } 00170 } 00171 00172 00173 // write the new value 00174 00175 template <int W> 00176 inline 00177 void 00178 sc_signal_rv<W>::write( const data_type& value_ ) 00179 { 00180 sc_process_b* cur_proc = sc_get_current_process_b(); 00181 00182 bool value_changed = false; 00183 bool found = false; 00184 00185 for( int i = m_proc_vec.size() - 1; i >= 0; -- i ) { 00186 if( cur_proc == m_proc_vec[i] ) { 00187 if( value_ != *m_val_vec[i] ) { 00188 *m_val_vec[i] = value_; 00189 value_changed = true; 00190 } 00191 found = true; 00192 break; 00193 } 00194 } 00195 00196 if( ! found ) { 00197 m_proc_vec.push_back( cur_proc ); 00198 m_val_vec.push_back( new data_type( value_ ) ); 00199 value_changed = true; 00200 } 00201 00202 if( value_changed ) { 00203 this->request_update(); 00204 } 00205 } 00206 00207 00208 template <int W> 00209 inline 00210 void 00211 sc_signal_rv<W>::update() 00212 { 00213 sc_lv_resolve<W>::resolve( this->m_new_val, m_val_vec ); 00214 base_type::update(); 00215 } 00216 00217 } // namespace sc_core 00218 00219 //$Log: sc_signal_rv.h,v $ 00220 //Revision 1.4 2011/08/26 20:45:44 acg 00221 // Andy Goodrich: moved the modification log to the end of the file to 00222 // eliminate source line number skew when check-ins are done. 00223 // 00224 //Revision 1.3 2011/04/19 02:36:26 acg 00225 // Philipp A. Hartmann: new aysnc_update and mutex support. 00226 // 00227 //Revision 1.2 2011/02/18 20:23:45 acg 00228 // Andy Goodrich: Copyright update. 00229 // 00230 //Revision 1.1.1.1 2006/12/15 20:20:04 acg 00231 //SystemC 2.3 00232 // 00233 //Revision 1.3 2006/03/21 00:00:27 acg 00234 // Andy Goodrich: changed name of sc_get_current_process_base() to be 00235 // sc_get_current_process_b() since its returning an sc_process_b instance. 00236 // 00237 //Revision 1.2 2006/01/03 23:18:26 acg 00238 //Changed copyright to include 2006. 00239 // 00240 //Revision 1.1.1.1 2005/12/19 23:16:43 acg 00241 //First check in of SystemC 2.1 into its own archive. 00242 // 00243 //Revision 1.10 2005/09/15 23:01:52 acg 00244 //Added std:: prefix to appropriate methods and types to get around 00245 //issues with the Edison Front End. 00246 // 00247 //Revision 1.9 2005/06/10 22:43:55 acg 00248 //Added CVS change log annotation. 00249 // 00250 00251 #endif 00252 00253 // Taf!