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_H_
00038 #define RC_FIFO_H_
00039
00040 #include "ReChannel/components/rc_prim_channel.h"
00041 #include "ReChannel/components/rc_report_ids.h"
00042 #include <deque>
00043
00044 namespace ReChannel {
00045
00049 template<class T>
00050 class rc_fifo
00051 : public sc_fifo_in_if<T>,
00052 public sc_fifo_out_if<T>,
00053 public rc_prim_channel
00054 {
00055 public:
00056
00057 explicit rc_fifo(int size_=16)
00058 : rc_prim_channel(sc_gen_unique_name("fifo")),
00059 m_max_size(size_), m_num_read(0), m_num_written(0),
00060 m_reader_port(NULL), m_writer_port(NULL)
00061 { }
00062
00063 explicit rc_fifo(const char* name_, int size_=16)
00064 : rc_prim_channel(name_),
00065 m_max_size(size_), m_num_read(0), m_num_written(0),
00066 m_reader_port(NULL), m_writer_port(NULL)
00067 { }
00068
00069 virtual const char* kind() const
00070 { return "rc_fifo"; }
00071
00072 virtual void register_port(sc_port_base& port_, const char* if_name_);
00073
00074 inline virtual void read(T& value);
00075 inline virtual T read();
00076 inline virtual bool nb_read(T& value);
00077 inline virtual int num_available() const;
00078
00079 inline virtual void write(const T& value);
00080 inline virtual bool nb_write(const T& value);
00081 inline virtual int num_free() const;
00082
00083 virtual const sc_event& data_written_event() const
00084 { return m_data_written_event; }
00085 virtual const sc_event& data_read_event() const
00086 { return m_data_read_event; }
00087
00088 operator T ()
00089 { return this->read(); }
00090
00091 rc_fifo<T>& operator=(const T& value)
00092 { this->write(value); return *this; }
00093
00094 virtual void print(std::ostream& os=std::cout) const;
00095 virtual void dump(std::ostream& os=std::cout) const;
00096
00097 protected:
00098
00099 virtual void update();
00100
00101 RC_ON_INIT_RESETTABLE()
00102 {
00103
00104 if (!m_deque.empty()) {
00105 m_reset_values.insert(
00106 m_reset_values.end(), m_deque.begin(), m_deque.end());
00107 }
00108 }
00109
00110 RC_ON_RESET()
00111 {
00112
00113 m_deque.clear();
00114 m_num_read = 0;
00115 m_num_written = 0;
00116 m_data_read_event.cancel();
00117 m_data_written_event.cancel();
00118
00119
00120 if (!m_reset_values.empty()) {
00121 m_deque.insert(
00122 m_deque.end(), m_reset_values.begin(),
00123 m_reset_values.end());
00124 }
00125 }
00126
00127 protected:
00128
00129 std::deque<T> m_deque;
00130 const unsigned int m_max_size;
00131 unsigned int m_num_read;
00132 unsigned int m_num_written;
00133
00134 sc_event m_data_read_event;
00135 sc_event m_data_written_event;
00136
00137 const sc_port_base* m_reader_port;
00138 const sc_port_base* m_writer_port;
00139
00140 std::vector<T> m_reset_values;
00141
00142 private:
00143
00144 rc_fifo(const rc_fifo<T>& other);
00145 rc_fifo<T>& operator=(const rc_fifo<T>& other);
00146 };
00147
00148
00149
00150 template<class T>
00151 inline int rc_fifo<T>::num_available() const
00152 {
00153 if (!this->rc_is_active()) {
00154 return 0;
00155 }
00156 return (int)(m_deque.size() - m_num_written);
00157 }
00158
00159 template<class T>
00160 inline int rc_fifo<T>::num_free() const
00161 {
00162 if (!this->rc_is_active()) {
00163 return 0;
00164 }
00165 return m_max_size - m_deque.size();
00166 }
00167
00168 template<class T>
00169 inline void rc_fifo<T>::read(T& value)
00170 {
00171 while (this->num_available() == 0) {
00172 this->wait(m_data_written_event);
00173 }
00174 value = m_deque.front();
00175 m_deque.pop_front();
00176 m_num_read++;
00177 this->request_update();
00178 }
00179
00180 template<class T>
00181 inline T rc_fifo<T>::read()
00182 {
00183 T tmp;
00184 this->read(tmp);
00185 return tmp;
00186 }
00187
00188 template<class T>
00189 inline bool rc_fifo<T>::nb_read(T& value)
00190 {
00191 if (this->num_available() == 0) {
00192 return false;
00193 } else {
00194 value = m_deque.front();
00195 m_deque.pop_front();
00196 m_num_read++;
00197 this->request_update();
00198 return true;
00199 }
00200 }
00201
00202 template<class T>
00203 inline void rc_fifo<T>::write(const T& value)
00204 {
00205 while(this->num_free() == 0) {
00206 this->wait(m_data_read_event);
00207 }
00208 m_num_written++;
00209 m_deque.push_back(value);
00210 this->request_update();
00211 }
00212
00213 template<class T>
00214 inline bool rc_fifo<T>::nb_write(const T& value)
00215 {
00216 if (this->num_free() == 0) {
00217 return false;
00218 } else {
00219 m_num_written++;
00220 m_deque.push_back(value);
00221 this->request_update();
00222 return true;
00223 }
00224 }
00225
00226
00227
00228 template<class T>
00229 void rc_fifo<T>::register_port(
00230 sc_port_base& port_, const char* if_name_)
00231 {
00232 const std::string if_name(if_name_);
00233 if (if_name == typeid(sc_fifo_in_if<T>).name()) {
00234 if (m_reader_port != NULL) {
00235 RC_REPORT_ERROR(RC_ID_FIFO_BINDING_ERROR_,
00236 "more than one FIFO reader"
00237 " (in rc_fifo '" << this->name() << "')");
00238 }
00239 m_reader_port = &port_;
00240 } else {
00241 if (m_writer_port != NULL) {
00242 RC_REPORT_ERROR(RC_ID_FIFO_BINDING_ERROR_,
00243 "more than one FIFO writer"
00244 " (in rc_fifo '" << this->name() << "')");
00245 }
00246 m_writer_port = &port_;
00247 }
00248 }
00249
00250 template<class T>
00251 void rc_fifo<T>::print(std::ostream& os) const
00252 {
00253 for(typename std::deque<T>::const_reverse_iterator it =
00254 m_deque.rbegin();
00255 it != m_deque.rend();
00256 ++it)
00257 {
00258 os << (*it) << std::endl;
00259 }
00260 }
00261
00262 template<class T>
00263 void rc_fifo<T>::dump(std::ostream& os) const
00264 {
00265 os << "name = " << this->name() << ::std::endl;
00266 unsigned int i = 0;
00267 for(typename std::deque<T>::const_iterator it = m_deque.begin();
00268 it != m_deque.end();
00269 ++it)
00270 {
00271 os << "value[" << i << "] = " << (*it) << ::std::endl;
00272 ++i;
00273 }
00274 }
00275
00276 template<class T>
00277 void rc_fifo<T>::update()
00278 {
00279 if (this->rc_is_active()) {
00280 if (m_num_read > 0) {
00281 m_data_read_event.notify(SC_ZERO_TIME);
00282 }
00283 if (m_num_written > 0) {
00284 m_data_written_event.notify(SC_ZERO_TIME);
00285 }
00286 }
00287 m_num_read = 0;
00288 m_num_written = 0;
00289 }
00290
00291 }
00292
00293 #endif //RC_FIFO_H_
00294
00295
00296
00297
00298