rc_signal_rv.h

Go to the documentation of this file.
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 //

Generated on Tue Jan 1 23:14:06 2008 for ReChannel by  doxygen 1.5.3