sc_fifo.hh revision 13143:87d1097f49b0
12SN/A/* 21762SN/A * Copyright 2018 Google, Inc. 32SN/A * 42SN/A * Redistribution and use in source and binary forms, with or without 52SN/A * modification, are permitted provided that the following conditions are 62SN/A * met: redistributions of source code must retain the above copyright 72SN/A * notice, this list of conditions and the following disclaimer; 82SN/A * redistributions in binary form must reproduce the above copyright 92SN/A * notice, this list of conditions and the following disclaimer in the 102SN/A * documentation and/or other materials provided with the distribution; 112SN/A * neither the name of the copyright holders nor the names of its 122SN/A * contributors may be used to endorse or promote products derived from 132SN/A * this software without specific prior written permission. 142SN/A * 152SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262SN/A * 272665SN/A * Authors: Gabe Black 282665SN/A */ 292SN/A 302SN/A#ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 312SN/A#define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 322SN/A 332SN/A#include <list> 342SN/A 3511263Sandreas.sandberg@arm.com#include "../core/sc_module.hh" // for sc_gen_unique_name 3611263Sandreas.sandberg@arm.com#include "../core/sc_prim.hh" 372SN/A#include "sc_fifo_in_if.hh" 382SN/A#include "sc_fifo_out_if.hh" 392SN/A#include "warn_unimpl.hh" 402SN/A 414981SN/Anamespace sc_core 4211263Sandreas.sandberg@arm.com{ 4311263Sandreas.sandberg@arm.com 4411263Sandreas.sandberg@arm.comclass sc_port_base; 4512054Sgabeblack@google.comclass sc_event; 4656SN/A 4756SN/Atemplate <class T> 482SN/Aclass sc_fifo : public sc_fifo_in_if<T>, 491872SN/A public sc_fifo_out_if<T>, 5012055Sgabeblack@google.com public sc_prim_channel 5112055Sgabeblack@google.com{ 5212055Sgabeblack@google.com public: 5312055Sgabeblack@google.com explicit sc_fifo(int size=16) : 5412055Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 5512055Sgabeblack@google.com sc_prim_channel(sc_gen_unique_name("fifo")), 5612055Sgabeblack@google.com _size(size), _readsHappened(false) 5712055Sgabeblack@google.com {} 5812055Sgabeblack@google.com explicit sc_fifo(const char *name, int size=16) : 5912055Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 6012055Sgabeblack@google.com sc_prim_channel(name), _size(size), _readsHappened(false) 6112055Sgabeblack@google.com {} 6212055Sgabeblack@google.com virtual ~sc_fifo() {} 6312055Sgabeblack@google.com 6412055Sgabeblack@google.com virtual void 6512055Sgabeblack@google.com register_port(sc_port_base &, const char *) 6612055Sgabeblack@google.com { 6712055Sgabeblack@google.com sc_channel_warn_unimpl(__PRETTY_FUNCTION__); 6812055Sgabeblack@google.com } 6912055Sgabeblack@google.com 7012055Sgabeblack@google.com virtual void 7112055Sgabeblack@google.com read(T &t) 7212055Sgabeblack@google.com { 7312055Sgabeblack@google.com while (num_available() == 0) 7412055Sgabeblack@google.com sc_core::wait(_dataWriteEvent); 7512055Sgabeblack@google.com _readsHappened = true; 7612055Sgabeblack@google.com t = _entries.front(); 7712055Sgabeblack@google.com _entries.pop_front(); 7812055Sgabeblack@google.com request_update(); 7912055Sgabeblack@google.com } 8012055Sgabeblack@google.com virtual T 8112055Sgabeblack@google.com read() 8212055Sgabeblack@google.com { 8312055Sgabeblack@google.com T t; 8412055Sgabeblack@google.com read(t); 8512055Sgabeblack@google.com return t; 8612055Sgabeblack@google.com } 8712055Sgabeblack@google.com virtual bool 8812055Sgabeblack@google.com nb_read(T &t) 8912055Sgabeblack@google.com { 9012055Sgabeblack@google.com if (num_available()) { 9112055Sgabeblack@google.com read(t); 9212055Sgabeblack@google.com return true; 9312055Sgabeblack@google.com } else { 9412055Sgabeblack@google.com return false; 9512055Sgabeblack@google.com } 9612055Sgabeblack@google.com } 9712055Sgabeblack@google.com operator T() { return read(); } 9812055Sgabeblack@google.com 9912055Sgabeblack@google.com virtual void 10012055Sgabeblack@google.com write(const T &t) 10112055Sgabeblack@google.com { 10212055Sgabeblack@google.com while (num_free() == 0) 10312055Sgabeblack@google.com sc_core::wait(_dataReadEvent); 10412055Sgabeblack@google.com _pending.emplace_back(t); 10512055Sgabeblack@google.com request_update(); 10612055Sgabeblack@google.com } 10712055Sgabeblack@google.com virtual bool 10812055Sgabeblack@google.com nb_write(const T &t) 10912055Sgabeblack@google.com { 11012055Sgabeblack@google.com if (num_free()) { 11112055Sgabeblack@google.com write(t); 11212055Sgabeblack@google.com return true; 11312055Sgabeblack@google.com } else { 11412055Sgabeblack@google.com return false; 11512055Sgabeblack@google.com } 11612055Sgabeblack@google.com } 11712055Sgabeblack@google.com sc_fifo<T> & 11812055Sgabeblack@google.com operator = (const T &t) 11912055Sgabeblack@google.com { 12012055Sgabeblack@google.com write(t); 12112055Sgabeblack@google.com return *this; 12212055Sgabeblack@google.com } 12312055Sgabeblack@google.com 12412055Sgabeblack@google.com virtual const sc_event & 12512055Sgabeblack@google.com data_written_event() const 12612055Sgabeblack@google.com { 12712055Sgabeblack@google.com return _dataWriteEvent; 12812055Sgabeblack@google.com } 12912055Sgabeblack@google.com virtual const sc_event & 13012055Sgabeblack@google.com data_read_event() const 13112055Sgabeblack@google.com { 13212055Sgabeblack@google.com return _dataReadEvent; 13312055Sgabeblack@google.com } 13412055Sgabeblack@google.com 13512055Sgabeblack@google.com virtual int num_available() const { return _entries.size(); } 13612055Sgabeblack@google.com virtual int 1371872SN/A num_free() const 1381872SN/A { 1392SN/A return _size - _entries.size() - _pending.size(); 14012054Sgabeblack@google.com } 14112054Sgabeblack@google.com 14212054Sgabeblack@google.com virtual void 14312054Sgabeblack@google.com print(std::ostream &os=std::cout) const 1442SN/A { 14512055Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 1462SN/A pos != _pending.end(); pos++) { 1472SN/A os << *pos << ::std::endl; 14812054Sgabeblack@google.com } 14912054Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 15012055Sgabeblack@google.com pos != _entries.end(); pos++) { 1512SN/A os << *pos << ::std::endl; 1524981SN/A } 1534981SN/A } 1544981SN/A virtual void 1554981SN/A dump(std::ostream &os=std::cout) const 1564981SN/A { 1574981SN/A os << "name = " << name() << std::endl; 15811168SN/A int idx = 0; 15911168SN/A for (typename ::std::list<T>::iterator pos = _pending.begin(); 16012055Sgabeblack@google.com pos != _pending.end(); pos++) { 16112055Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 16212055Sgabeblack@google.com } 16312055Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 16412055Sgabeblack@google.com pos != _entries.end(); pos++) { 16512055Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 16612055Sgabeblack@google.com } 16712055Sgabeblack@google.com } 16812055Sgabeblack@google.com virtual const char *kind() const { return "sc_fifo"; } 16912055Sgabeblack@google.com 17012055Sgabeblack@google.com protected: 17112055Sgabeblack@google.com virtual void 17212055Sgabeblack@google.com update() 17312055Sgabeblack@google.com { 17412055Sgabeblack@google.com if (!_pending.empty()) { 17512055Sgabeblack@google.com _dataWriteEvent.notify(SC_ZERO_TIME); 1762SN/A _entries.insert(_entries.end(), _pending.begin(), _pending.end()); 1772SN/A _pending.clear(); 1784981SN/A } 17911263Sandreas.sandberg@arm.com if (_readsHappened) { 180 _readsHappened = false; 181 _dataReadEvent.notify(SC_ZERO_TIME); 182 } 183 } 184 185 private: 186 // Disabled 187 sc_fifo(const sc_fifo<T> &) : 188 sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel() 189 {} 190 sc_fifo &operator = (const sc_fifo<T> &) { return *this; } 191 192 sc_event _dataReadEvent; 193 sc_event _dataWriteEvent; 194 195 int _size; 196 mutable std::list<T> _entries; 197 mutable std::list<T> _pending; 198 bool _readsHappened; 199}; 200 201template <class T> 202inline std::ostream & 203operator << (std::ostream &os, const sc_fifo<T> &f) 204{ 205 f.print(os); 206 return os; 207} 208 209} // namespace sc_core 210 211#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 212