rc_signal.cpp

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 #include "rc_signal.h"
00038 
00039 namespace ReChannel {
00040 
00041 namespace internals {
00042 namespace signals {
00043 
00044 void report_binding_error(
00045     const sc_object& target, const sc_object& port1,
00046     const sc_object& port2)
00047 {
00048     RC_REPORT_ERROR(RC_ID_SIGNAL_BINDING_ERROR_,
00049         "signal cannot be bound to more than one output port"
00050         " (in rc_signal '" << target.name() << "', first port: '"
00051         << port1.name() << "', second port: '"
00052         << port2.name() << "')");
00053 }
00054 
00055 void report_driver_conflict(
00056     const sc_object& target, const sc_object& driver1,
00057     const sc_object& driver2)
00058 {
00059     RC_REPORT_ERROR(RC_ID_SIGNAL_DRIVER_CONFLICT_,
00060         "signal cannot have more than one driver"
00061         " (in rc_signal '" << target.name() << "', first driver: '"
00062         << driver1.name() << "', second driver: '"
00063         << driver2.name() << "')");
00064 }
00065 
00066 } // namespace internals
00067 } // namespace signals
00068 
00069 void rc_signal<bool>::register_process_control(
00070     rc_process_control& pctrl, bool active_level) const
00071 {
00072     p_pctrl_set[(active_level ? 1 : 0)].insert(&pctrl);
00073 }
00074 
00075 void rc_signal<bool>::unregister_process_control(
00076     rc_process_control& pctrl) const
00077 {
00078     p_pctrl_set[0].erase(&pctrl);
00079     p_pctrl_set[1].erase(&pctrl);
00080 }
00081 
00082 bool rc_signal<bool>::get_current_level() const
00083 {
00084     return m_current_value;
00085 }
00086 
00087 const sc_signal<bool>* rc_signal<bool>::get_underlying_reset_signal() const
00088 {
00089     if (!this->rc_has_reconfigurable()) {
00090         return &this->_rc_get_reset_signal();
00091     } else {
00092         return NULL;
00093     }
00094 }
00095 
00096 void rc_signal<bool>::update()
00097 {
00098     if (this->rc_is_active() && !(m_new_value == m_current_value)) {
00099         m_current_value = m_new_value;
00100         if (m_notify_value_changed_event) {
00101             m_value_changed_event.notify(SC_ZERO_TIME);
00102         }
00103         if (m_new_value) {
00104             if (m_notify_posedge_event) {
00105                 m_posedge_event.notify(SC_ZERO_TIME);
00106             }
00107         } else {
00108             if (m_notify_negedge_event) {
00109                 m_negedge_event.notify(SC_ZERO_TIME);
00110             }
00111         }
00112         m_delta = sc_delta_count();
00113 
00114         pctrl_set& set_ = p_pctrl_set[(m_new_value ? 1 : 0)];
00115         for (pctrl_set::iterator it = set_.begin();
00116             it != set_.end();
00117             ++it)
00118         {
00119             (*it)->deactivate();
00120         }
00121     }
00122 }
00123 
00124 sc_signal<bool>& rc_signal<bool>::_rc_get_reset_signal() const
00125 {
00126     if (p_reset_signal == NULL) {
00127         p_reset_signal =
00128             new sc_signal<bool>(
00129                 sc_gen_unique_name("_rc_signal_reset_signal"));
00130         sc_spawn_options opt;
00131         {
00132             opt.spawn_method();
00133             opt.set_sensitivity(&this->value_changed_event());
00134         }
00135         sc_spawn(
00136             sc_bind(
00137                 &rc_signal<bool>::_rc_reset_updater_proc,
00138                 const_cast<rc_signal<bool>*>(this)),
00139             sc_gen_unique_name("_rc_reset_updater_proc"), &opt);
00140     }
00141     return *p_reset_signal;
00142 }
00143 
00144 void rc_signal<bool>::_rc_reset_updater_proc()
00145 {
00146     p_reset_signal->write(this->read());
00147 }
00148 
00149 void rc_signal<sc_dt::sc_logic>::update()
00150 {
00151     if (this->rc_is_active() && !(m_new_value == m_current_value)) {
00152         m_current_value = m_new_value;
00153         if (m_notify_value_changed_event) {
00154             m_value_changed_event.notify(SC_ZERO_TIME);
00155         }
00156         if (m_new_value == sc_dt::SC_LOGIC_1) {
00157             if (m_notify_posedge_event) {
00158                 m_posedge_event.notify(SC_ZERO_TIME);
00159             }
00160         } else if (m_new_value == sc_dt::SC_LOGIC_0) {
00161             if (m_notify_negedge_event) {
00162                 m_negedge_event.notify(SC_ZERO_TIME);
00163             }
00164         }
00165         m_delta = sc_delta_count();
00166     }
00167 }
00168 
00169 } // namespace ReChannel
00170 
00171 //
00172 // $Id: rc_signal.cpp,v 1.4 2007/12/20 20:33:51 felke Exp $
00173 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/components/rc_signal.cpp,v $
00174 //

Generated on Tue Jan 1 23:13:58 2008 for ReChannel by  doxygen 1.5.3