00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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 }
00484
00485 #endif // RC_FIFO_FILTERS_H_
00486
00487
00488
00489
00490