rc_fifo_filters.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_FIFO_FILTERS_H_
00038 #define RC_FIFO_FILTERS_H_
00039 
00040 #include "ReChannel/communication/filters/rc_abstract_prim_filter.h"
00041 #include "ReChannel/communication/accessors/rc_fifo_accessors.h"
00042 
00043 namespace ReChannel {
00044 
00048 template<class T>
00049 class rc_fifo_in_filter
00050     : public rc_abstract_prim_filter<sc_fifo_in_if<T> >
00051 {
00052 public:
00053     typedef rc_abstract_prim_filter<sc_fifo_in_if<T> > base_type;
00054     typedef typename base_type::accessor_type          accessor_type;
00055     typedef typename base_type::sync_callback          sync_callback;
00056 
00057     using base_type::RC_POSSIBLE_DEACTIVATION_;
00058     using base_type::RC_MODIFY_TRANSACTION_;
00059     using base_type::m_sync_callback_before;
00060     using base_type::m_sync_callback_after;
00061 
00062 public:
00063 
00064     explicit rc_fifo_in_filter(int read_limit=-1);
00065 
00066     rc_fifo_in_filter(
00067         const sync_callback& func_before, const sync_callback& func_after,
00068         int read_limit=-1);
00069 
00070     explicit rc_fifo_in_filter(
00071         rc_transaction_counter& tc, int tc_modify=+1, int read_limit=-1);
00072 
00073     virtual void read(T& value);
00074 
00075     virtual T read();
00076 
00077     virtual bool nb_read(T& value);
00078 
00079     virtual int num_available() const;
00080 
00081     inline int get_read_limit() const
00082         { return p_max_available; }
00083 
00084     inline void set_read_limit(int read_limit_)
00085     {
00086         if (read_limit_ != 0 && && p_max_available == 0
00087         && base_type::num_available() > 0)
00088         {
00089             this->trigger_written_event();
00090         }
00091         p_max_available = (read_limit_ >= 0 ? read_limit_ : -1);
00092     }
00093 
00094     inline int incr_read_limit(int amount_=1);
00095 
00096     inline int decr_read_limit(int amount_=1)
00097         { return this->incr_read_limit(-amount_); }
00098 
00099     inline void reset_read_limit()
00100     {
00101         if (p_max_available_default != 0 && p_max_available == 0
00102         && base_type::num_available() > 0)
00103         {
00104             this->trigger_written_event();
00105         }
00106         p_max_available = p_max_available_default;
00107     }
00108 
00109     inline virtual rc_event_filter* rc_get_event_filter()
00110         { return this; }
00111 
00112     inline T get_last_read() const
00113         { return p_last_read_value; }
00114 
00115 protected:
00116 
00117     virtual void rc_on_target_changed();
00118 
00119     inline virtual bool rc_on_event(const sc_event& e)
00120     {
00121         if (&e != &this->data_written_event()) {
00122             return false;
00123         }
00124         return (p_max_available != 0);
00125     }
00126 
00127     virtual void rc_set_event_trigger(
00128         const sc_event& e, rc_event_trigger& t)
00129     {
00130         if (&e == &this->data_written_event()) {
00131             p_event_trigger = &t;
00132         }
00133     }
00134 
00135     virtual void rc_clear_event_trigger(const sc_event& e)
00136     {
00137         if (&e == &this->data_written_event()) {
00138             p_event_trigger = NULL;
00139         }
00140     }
00141 
00142     inline void trigger_written_event()
00143     {
00144         if (p_event_trigger != NULL) {
00145             p_event_trigger->rc_trigger_event(
00146                 this->data_written_event());
00147         }
00148     }
00149 
00150 private:
00151     int p_max_available_default;
00152     int p_max_available;
00153     rc_event_trigger* p_event_trigger;
00154     T   p_last_read_value;
00155 };
00156 
00160 template<class T>
00161 class rc_fifo_out_filter
00162     : public rc_abstract_prim_filter<sc_fifo_out_if<T> >
00163 {
00164 public:
00165     typedef rc_abstract_prim_filter<sc_fifo_out_if<T> > base_type;
00166     typedef typename base_type::accessor_type           accessor_type;
00167     typedef typename base_type::sync_callback           sync_callback;
00168 
00169     using base_type::RC_POSSIBLE_DEACTIVATION_;
00170     using base_type::RC_MODIFY_TRANSACTION_;
00171     using base_type::m_sync_callback_before;
00172     using base_type::m_sync_callback_after;
00173 
00174 public:
00175 
00176     explicit rc_fifo_out_filter(int write_limit=-1);
00177 
00178     rc_fifo_out_filter(
00179         const sync_callback& func_before, const sync_callback& func_after,
00180         int write_limit=-1);
00181 
00182     explicit rc_fifo_out_filter(
00183         rc_transaction_counter& tc, int tc_modify=-1, int write_limit=-1);
00184 
00185     virtual void write(const T& value);
00186 
00187     virtual bool nb_write(const T& value);
00188 
00189     virtual int num_free() const;
00190 
00191     inline int get_write_limit() const
00192         { return p_max_free; }
00193 
00194     inline void set_write_limit(int write_limit_)
00195     {
00196         if (write_limit_ != 0 && p_max_free == 0
00197         && base_type::num_free() > 0)
00198         {
00199             this->trigger_read_event();
00200         }
00201         p_max_free = (write_limit_ >= 0 ? write_limit_ : -1);
00202     }
00203 
00204     inline int incr_write_limit(int amount_=1);
00205 
00206     inline int decr_write_limit(int amount_=1)
00207         { return this->incr_write_limit(-amount_); }
00208 
00209     inline void reset_write_limit()
00210     {
00211         if (p_max_free_default != 0 && p_max_free == 0
00212         && base_type::num_free() > 0)
00213         {
00214             this->trigger_read_event();
00215         }
00216         p_max_free = p_max_free_default;
00217     }
00218 
00219     inline virtual rc_event_filter* rc_get_event_filter()
00220         { return this; }
00221 
00222     inline T get_last_written() const
00223         { return p_last_written_value; }
00224 
00225 protected:
00226 
00227     virtual void rc_on_target_changed();
00228 
00229     inline virtual bool rc_on_event(const sc_event& e)
00230     {
00231         if (&e != &this->data_read_event()) {
00232             return false;
00233         }
00234         return (p_max_free != 0);
00235     }
00236 
00237     virtual void rc_set_event_trigger(
00238         const sc_event& e, rc_event_trigger& t)
00239     {
00240         if (&e == &this->data_read_event()) {
00241             p_event_trigger = &t;
00242         }
00243     }
00244 
00245     virtual void rc_clear_event_trigger(const sc_event& e)
00246     {
00247         if (&e == &this->data_read_event()) {
00248             p_event_trigger = NULL;
00249         }
00250     }
00251 
00252     inline void trigger_read_event()
00253     {
00254         if (p_event_trigger != NULL) {
00255             p_event_trigger->rc_trigger_event(
00256                 this->data_read_event());
00257         }
00258     }
00259 
00260 private:
00261     int p_max_free_default;
00262     int p_max_free;
00263     rc_event_trigger* p_event_trigger;
00264     T   p_last_written_value;
00265 };
00266 
00267 /* inline code */
00268 
00269 template<class T>
00270 inline
00271 int rc_fifo_in_filter<T>::incr_read_limit(int amount_)
00272 {
00273     if (p_max_available >= 0)
00274     {
00275         if (amount_ > 0 && p_max_available == 0
00276         && base_type::num_available() > 0)
00277         {
00278             this->trigger_written_event();
00279         }
00280         p_max_available += amount_;
00281         if (p_max_available < 0) {
00282             p_max_available = 0;
00283         }
00284     }
00285     return p_max_available;
00286 }
00287 
00288 template<class T>
00289 inline
00290 int rc_fifo_out_filter<T>::incr_write_limit(int amount_)
00291 {
00292     if (p_max_free >= 0)
00293     {
00294         if (amount_ > 0 && p_max_free == 0
00295         && base_type::num_free() > 0) {
00296             this->trigger_read_event();
00297         }
00298         p_max_free += amount_;
00299         if (p_max_free < 0) {
00300             p_max_free = 0;
00301         }
00302     }
00303     return p_max_free;
00304 }
00305 
00306 /* template code */
00307 
00308 template<class T>
00309 rc_fifo_in_filter<T>::rc_fifo_in_filter(int read_limit)
00310     : p_max_available_default(read_limit >= 0 ? read_limit : -1),
00311       p_max_available(p_max_available_default), p_event_trigger(NULL),
00312       p_last_read_value(rc_undefined_value<T>())
00313 { }
00314 
00315 template<class T>
00316 rc_fifo_in_filter<T>::rc_fifo_in_filter(
00317     const sync_callback& func_before, const sync_callback& func_after,
00318     int read_limit)
00319     : base_type(func_before, func_after),
00320       p_max_available_default(read_limit >= 0 ? read_limit : -1),
00321       p_max_available(p_max_available_default), p_event_trigger(NULL),
00322       p_last_read_value(rc_undefined_value<T>())
00323 { }
00324 
00325 template<class T>
00326 rc_fifo_in_filter<T>::rc_fifo_in_filter(
00327     rc_transaction_counter& tc, int tc_modify, int read_limit)
00328     : p_max_available_default(read_limit >= 0 ? read_limit : -1),
00329       p_max_available(p_max_available_default), p_event_trigger(NULL),
00330       p_last_read_value(rc_undefined_value<T>())
00331 {
00332     m_sync_callback_before =
00333         this->rc_predefined_sync_callback(
00334             (tc_modify >= 0 ?
00335                 RC_POSSIBLE_DEACTIVATION_ : RC_MODIFY_TRANSACTION_),
00336             tc, tc_modify);
00337     m_sync_callback_after =
00338         this->rc_predefined_sync_callback(
00339             (tc_modify >= 0 ?
00340                 RC_MODIFY_TRANSACTION_ : RC_POSSIBLE_DEACTIVATION_),
00341             tc, tc_modify);
00342 }
00343 
00344 template<class T>
00345 void rc_fifo_in_filter<T>::read(T& value)
00346 {
00347     this->rc_sync_callback_before();
00348     base_type::read(value);
00349     if (p_max_available > 0) {
00350         p_max_available--;
00351     }
00352     p_last_read_value = value;
00353     this->rc_sync_callback_after();
00354 }
00355 
00356 template<class T>
00357 T rc_fifo_in_filter<T>::read()
00358 {
00359     this->rc_sync_callback_before();
00360     p_last_read_value = base_type::read();
00361     if (p_max_available > 0) {
00362         p_max_available--;
00363     }
00364     this->rc_sync_callback_after();
00365     return p_last_read_value;
00366 }
00367 
00368 template<class T>
00369 bool rc_fifo_in_filter<T>::nb_read(T& value)
00370 {
00371     this->rc_nb_sync_callback_before();
00372     const bool has_read =
00373         (p_max_available != 0 && base_type::nb_read(value));
00374     if (has_read) {
00375         if (p_max_available > 0) {
00376             p_max_available--;
00377         }
00378         p_last_read_value = value;
00379         this->rc_nb_sync_callback_after();
00380     }
00381     return has_read;
00382 }
00383 
00384 template<class T>
00385 int rc_fifo_in_filter<T>::num_available() const
00386 {
00387     const int num = base_type::num_available();
00388     if (p_max_available == -1) {
00389         return num;
00390     } else {
00391         return (num <= p_max_available ? num : p_max_available);
00392     }
00393 }
00394 
00395 template<class T>
00396 void rc_fifo_in_filter<T>::rc_on_target_changed()
00397 {
00398     p_max_available = p_max_available_default;
00399     base_type::rc_on_target_changed();
00400 }
00401 
00402 template<class T>
00403 rc_fifo_out_filter<T>::rc_fifo_out_filter(int write_limit)
00404     : p_max_free_default(write_limit >= 0 ? write_limit : -1),
00405       p_max_free(p_max_free_default), p_event_trigger(NULL),
00406       p_last_written_value(rc_undefined_value<T>())
00407 { }
00408 
00409 template<class T>
00410 rc_fifo_out_filter<T>::rc_fifo_out_filter(
00411     const sync_callback& func_before, const sync_callback& func_after,
00412     int write_limit)
00413     : base_type(func_before, func_after),
00414       p_max_free_default(write_limit >= 0 ? write_limit : -1),
00415       p_max_free(p_max_free_default), p_event_trigger(NULL),
00416       p_last_written_value(rc_undefined_value<T>())
00417 { }
00418 
00419 template<class T>
00420 rc_fifo_out_filter<T>::rc_fifo_out_filter(
00421     rc_transaction_counter& tc, int tc_modify, int write_limit)
00422     : p_max_free_default(write_limit >= 0 ? write_limit : -1),
00423       p_max_free(p_max_free_default), p_event_trigger(NULL),
00424       p_last_written_value(rc_undefined_value<T>())
00425 {
00426     if (tc_modify < 0) {
00427         m_sync_callback_after =
00428             this->rc_predefined_sync_callback(
00429                 RC_MODIFY_TRANSACTION_, tc, tc_modify);
00430     } else {
00431         m_sync_callback_before =
00432             this->rc_predefined_sync_callback(
00433                 RC_MODIFY_TRANSACTION_, tc, tc_modify);
00434     }
00435 }
00436 
00437 template<class T>
00438 void rc_fifo_out_filter<T>::write(const T& value)
00439 {
00440     this->rc_sync_callback_before();
00441     base_type::write(value);
00442     if (p_max_free > 0) {
00443         p_max_free--;
00444     }
00445     p_last_written_value = value;
00446     this->rc_sync_callback_after();
00447 }
00448 
00449 template<class T>
00450 bool rc_fifo_out_filter<T>::nb_write(const T& value)
00451 {
00452     this->rc_nb_sync_callback_before();
00453     if (p_max_free != 0 && base_type::nb_write(value)) {
00454         if (p_max_free > 0) {
00455             p_max_free--;
00456         }
00457         p_last_written_value = value;
00458         this->rc_nb_sync_callback_after();
00459         return true;
00460     } else {
00461         return false;
00462     }
00463 }
00464 
00465 template<class T>
00466 int rc_fifo_out_filter<T>::num_free() const
00467 {
00468     const int num = base_type::num_free();
00469     if (p_max_free == -1) {
00470         return num;
00471     } else {
00472         return (num <= p_max_free ? num : p_max_free);
00473     }
00474 }
00475 
00476 template<class T>
00477 void rc_fifo_out_filter<T>::rc_on_target_changed()
00478 {
00479     p_max_free = p_max_free_default;
00480     base_type::rc_on_target_changed();
00481 }
00482 
00483 } // namespace ReChannel
00484 
00485 #endif // RC_FIFO_FILTERS_H_
00486 
00487 //
00488 // $Id: rc_fifo_filters.h,v 1.9 2008/01/01 13:49:24 felke Exp $
00489 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/communication/filters/rc_fifo_filters.h,v $
00490 //

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