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_SIGNAL_RV_H_ 00038 #define RC_SIGNAL_RV_H_ 00039 00040 #include "ReChannel/components/rc_signal.h" 00041 00042 namespace ReChannel { 00043 00047 template<int W> 00048 class rc_signal_rv 00049 : public rc_signal<sc_lv<W> > 00050 { 00051 private: 00052 typedef sc_dt::sc_logic_value_t data_type; 00053 typedef sc_dt::sc_lv<W> value_type; 00054 enum logic_values { 00055 Log_0 = 0, 00056 Log_1, 00057 Log_Z, 00058 Log_X 00059 }; 00060 struct written 00061 { 00062 written(const sc_process_handle& hproc_, const value_type& value_) 00063 : hproc(hproc_) 00064 { 00065 for (int i=0; i < W; ++i) { 00066 value[i] = sc_logic(value_[i]).value(); 00067 } 00068 } 00069 sc_process_handle hproc; 00070 data_type value[W]; 00071 }; 00072 00073 private: 00074 typedef rc_signal_rv this_type; 00075 typedef rc_signal<sc_lv<W> > base_type; 00076 00077 typedef typename std::vector<written> written_vector; 00078 00079 using base_type::m_new_value; 00080 using base_type::m_reset_value; 00081 00082 public: 00083 explicit rc_signal_rv( 00084 const sc_module_name& name_=sc_gen_unique_name("signal_rv")); 00085 00086 virtual const char* kind() const 00087 { return "rc_signal_rv"; } 00088 00089 virtual void register_port(sc_port_base& port_, const char* if_name_) 00090 { } 00091 00092 virtual void write(const value_type& value); 00093 00094 this_type& operator=(const value_type& value) 00095 { this->write(value); return *this; } 00096 00097 this_type& operator=(const this_type& signal_) 00098 { this->write(signal_); return *this; } 00099 00100 protected: 00101 00102 RC_ON_INIT_RESETTABLE() 00103 { 00104 base_type::rc_on_init_resettable(); 00105 if (!m_written_vector.empty()) { 00106 m_reset_written_vector = m_written_vector; 00107 } 00108 } 00109 00110 RC_ON_RESET() 00111 { 00112 base_type::rc_on_reset(); 00113 for (int i=0; i < W; ++i) { 00114 for (int j=0; j < 4; ++j) { 00115 m_value_count[i][j] = 0; 00116 } 00117 } 00118 if (m_reset_written_vector.empty()) { 00119 m_written_vector.clear(); 00120 } else { 00121 m_written_vector = m_reset_written_vector; 00122 for (typename written_vector::iterator it = 00123 m_written_vector.begin(); 00124 it != m_written_vector.end(); 00125 ++it) 00126 { 00127 data_type* written_value = (*it).value; 00128 for (int i=0; i < W; ++i) { 00129 int value = sc_logic(written_value[i]).value(); 00130 if (value != Log_Z) { 00131 m_value_count[i][value] += 1; 00132 } 00133 } 00134 } 00135 } 00136 } 00137 00138 protected: 00139 00140 written_vector m_reset_written_vector; 00141 written_vector m_written_vector; 00142 int m_value_count[W][4]; 00143 00144 private: 00145 // diabled 00146 rc_signal_rv(const this_type& signal_); 00147 }; 00148 00149 /* template code */ 00150 00151 template<int W> 00152 rc_signal_rv<W>::rc_signal_rv(const sc_module_name& name_) 00153 : base_type(name_) 00154 { 00155 for (int i=0; i < W; ++i) { 00156 for (int j=0; j < 4; ++j) { 00157 m_value_count[i][j] = 0; 00158 } 00159 } 00160 } 00161 00162 template<int W> 00163 void rc_signal_rv<W>::write(const value_type& value) 00164 { 00165 if (this->rc_is_active() || !sc_is_running()) { 00166 sc_process_handle hproc = sc_get_current_process_handle(); 00167 written* found = NULL; 00168 00169 for(typename written_vector::iterator it = 00170 m_written_vector.begin(); 00171 it != m_written_vector.end(); 00172 ++it) 00173 { 00174 if (hproc.get_process_object() 00175 == (*it).hproc.get_process_object()) 00176 { 00177 found = &(*it); 00178 break; 00179 } 00180 } 00181 00182 bool changed = false; 00183 00184 if (found == NULL) { 00185 bool is_Z = true; 00186 for(int i=0; i < W; ++i) { 00187 if (value[i] != Log_Z) { 00188 is_Z = false; 00189 break; 00190 } 00191 } 00192 if (is_Z) { 00193 return; 00194 } 00195 m_written_vector.push_back(written(hproc, value)); 00196 found = &m_written_vector.back(); 00197 for (int i=0; i < W; ++i) { 00198 data_type value_ = sc_logic(value[i]).value(); 00199 if (value_ != (data_type)Log_Z) { 00200 ++m_value_count[i][value_]; 00201 } 00202 } 00203 changed = true; 00204 } else { 00205 bool is_Z = true; 00206 for (int i=0; i < W; ++i) { 00207 data_type curr_value_ = sc_logic(found->value[i]).value(); 00208 data_type value_ = sc_logic(value[i]).value(); 00209 if (value_ != (data_type)Log_Z) { 00210 is_Z = false; 00211 } 00212 if (value_ != curr_value_) { 00213 changed = true; 00214 --m_value_count[i][curr_value_]; 00215 if (value_ != (data_type)Log_Z) { 00216 ++m_value_count[i][value_]; 00217 found->value[i] = value_; 00218 } 00219 } 00220 } 00221 if (is_Z) { 00222 if (found != &m_written_vector.back()) { 00223 *found = m_written_vector.back(); 00224 } 00225 m_written_vector.pop_back(); 00226 } 00227 } 00228 00229 if (changed) { 00230 for (int i=0; i < W; ++i) { 00231 int* value_count = m_value_count[i]; 00232 if (value_count[Log_X] > 0) { 00233 m_new_value[i] = Log_X; 00234 } else if (value_count[Log_0] > 0) { 00235 m_new_value[i] = 00236 (value_count[Log_1] == 0 00237 ? Log_0 : Log_X); 00238 } else if (value_count[Log_1] > 0) { 00239 m_new_value[i] = 00240 (value_count[Log_0] == 0 00241 ? Log_1 : Log_X); 00242 } else { 00243 m_new_value[i] = Log_Z; 00244 } 00245 } 00246 this->request_update(); 00247 } 00248 } 00249 } 00250 00251 } // namespace ReChannel 00252 00253 #endif // RC_SIGNAL_RV_H_ 00254 00255 // 00256 // $Id: rc_signal_rv.h,v 1.9 2007/12/20 20:33:51 felke Exp $ 00257 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/components/rc_signal_rv.h,v $ 00258 //