sc_fifo.hh revision 13407
112841Sgabeblack@google.com/* 212841Sgabeblack@google.com * Copyright 2018 Google, Inc. 312841Sgabeblack@google.com * 412841Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512841Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612841Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812841Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012841Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112841Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212841Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312841Sgabeblack@google.com * this software without specific prior written permission. 1412841Sgabeblack@google.com * 1512841Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612841Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712841Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812841Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912841Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012841Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112841Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212841Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312841Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412841Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512841Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612841Sgabeblack@google.com * 2712841Sgabeblack@google.com * Authors: Gabe Black 2812841Sgabeblack@google.com */ 2912841Sgabeblack@google.com 3012841Sgabeblack@google.com#ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 3112841Sgabeblack@google.com#define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 3212841Sgabeblack@google.com 3313123Sgabeblack@google.com#include <list> 3413274Sgabeblack@google.com#include <string> 3513123Sgabeblack@google.com 3612841Sgabeblack@google.com#include "../core/sc_module.hh" // for sc_gen_unique_name 3712841Sgabeblack@google.com#include "../core/sc_prim.hh" 3813274Sgabeblack@google.com#include "../utils/sc_report_handler.hh" 3913324Sgabeblack@google.com#include "messages.hh" 4012841Sgabeblack@google.com#include "sc_fifo_in_if.hh" 4112841Sgabeblack@google.com#include "sc_fifo_out_if.hh" 4212841Sgabeblack@google.com 4312841Sgabeblack@google.comnamespace sc_core 4412841Sgabeblack@google.com{ 4512841Sgabeblack@google.com 4612841Sgabeblack@google.comclass sc_port_base; 4712841Sgabeblack@google.comclass sc_event; 4812841Sgabeblack@google.com 4912841Sgabeblack@google.comtemplate <class T> 5012841Sgabeblack@google.comclass sc_fifo : public sc_fifo_in_if<T>, 5112841Sgabeblack@google.com public sc_fifo_out_if<T>, 5212841Sgabeblack@google.com public sc_prim_channel 5312841Sgabeblack@google.com{ 5412841Sgabeblack@google.com public: 5512841Sgabeblack@google.com explicit sc_fifo(int size=16) : 5612841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 5713123Sgabeblack@google.com sc_prim_channel(sc_gen_unique_name("fifo")), 5813327Sgabeblack@google.com _size(size), _num_free(size), _num_available(0), 5913327Sgabeblack@google.com _readsHappened(false), _writesHappened(false), 6013327Sgabeblack@google.com _reader(NULL), _writer(NULL) 6112841Sgabeblack@google.com {} 6212841Sgabeblack@google.com explicit sc_fifo(const char *name, int size=16) : 6312841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 6413327Sgabeblack@google.com sc_prim_channel(name), _size(size), _num_free(size), 6513327Sgabeblack@google.com _num_available(0), _readsHappened(false), _writesHappened(false), 6613274Sgabeblack@google.com _reader(NULL), _writer(NULL) 6712841Sgabeblack@google.com {} 6812841Sgabeblack@google.com virtual ~sc_fifo() {} 6912841Sgabeblack@google.com 7012841Sgabeblack@google.com virtual void 7113274Sgabeblack@google.com register_port(sc_port_base &port, const char *iface_type_name) 7212841Sgabeblack@google.com { 7313274Sgabeblack@google.com std::string tn(iface_type_name); 7413274Sgabeblack@google.com if (tn == typeid(sc_fifo_in_if<T>).name() || 7513274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_in_if<T>).name()) { 7613324Sgabeblack@google.com if (_reader) 7713324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_READER_, ""); 7813274Sgabeblack@google.com _reader = &port; 7913274Sgabeblack@google.com } else if (tn == typeid(sc_fifo_out_if<T>).name() || 8013274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_out_if<T>).name()) { 8113324Sgabeblack@google.com if (_writer) 8213324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_WRITER_, ""); 8313274Sgabeblack@google.com _writer = &port; 8413274Sgabeblack@google.com } else { 8513324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_BIND_IF_TO_PORT_, 8613274Sgabeblack@google.com "sc_fifo<T> port not recognized"); 8713274Sgabeblack@google.com } 8812841Sgabeblack@google.com } 8912841Sgabeblack@google.com 9012841Sgabeblack@google.com virtual void 9113123Sgabeblack@google.com read(T &t) 9212841Sgabeblack@google.com { 9313123Sgabeblack@google.com while (num_available() == 0) 9413123Sgabeblack@google.com sc_core::wait(_dataWriteEvent); 9513123Sgabeblack@google.com _readsHappened = true; 9613123Sgabeblack@google.com t = _entries.front(); 9713123Sgabeblack@google.com _entries.pop_front(); 9813327Sgabeblack@google.com _num_available--; 9913123Sgabeblack@google.com request_update(); 10012841Sgabeblack@google.com } 10112841Sgabeblack@google.com virtual T 10212841Sgabeblack@google.com read() 10312841Sgabeblack@google.com { 10413123Sgabeblack@google.com T t; 10513123Sgabeblack@google.com read(t); 10613123Sgabeblack@google.com return t; 10712841Sgabeblack@google.com } 10812841Sgabeblack@google.com virtual bool 10913123Sgabeblack@google.com nb_read(T &t) 11012841Sgabeblack@google.com { 11113123Sgabeblack@google.com if (num_available()) { 11213123Sgabeblack@google.com read(t); 11313123Sgabeblack@google.com return true; 11413123Sgabeblack@google.com } else { 11513123Sgabeblack@google.com return false; 11613123Sgabeblack@google.com } 11712841Sgabeblack@google.com } 11813123Sgabeblack@google.com operator T() { return read(); } 11912841Sgabeblack@google.com 12012841Sgabeblack@google.com virtual void 12113123Sgabeblack@google.com write(const T &t) 12212841Sgabeblack@google.com { 12313123Sgabeblack@google.com while (num_free() == 0) 12413123Sgabeblack@google.com sc_core::wait(_dataReadEvent); 12513327Sgabeblack@google.com _writesHappened = true; 12613327Sgabeblack@google.com _entries.emplace_back(t); 12713327Sgabeblack@google.com _num_free--; 12813123Sgabeblack@google.com request_update(); 12912841Sgabeblack@google.com } 13012841Sgabeblack@google.com virtual bool 13113123Sgabeblack@google.com nb_write(const T &t) 13212841Sgabeblack@google.com { 13313123Sgabeblack@google.com if (num_free()) { 13413123Sgabeblack@google.com write(t); 13513123Sgabeblack@google.com return true; 13613123Sgabeblack@google.com } else { 13713123Sgabeblack@google.com return false; 13813123Sgabeblack@google.com } 13912841Sgabeblack@google.com } 14012841Sgabeblack@google.com sc_fifo<T> & 14113123Sgabeblack@google.com operator = (const T &t) 14212841Sgabeblack@google.com { 14313123Sgabeblack@google.com write(t); 14412841Sgabeblack@google.com return *this; 14512841Sgabeblack@google.com } 14612841Sgabeblack@google.com 14712841Sgabeblack@google.com virtual const sc_event & 14812853Sgabeblack@google.com data_written_event() const 14912841Sgabeblack@google.com { 15013123Sgabeblack@google.com return _dataWriteEvent; 15112841Sgabeblack@google.com } 15212841Sgabeblack@google.com virtual const sc_event & 15312841Sgabeblack@google.com data_read_event() const 15412841Sgabeblack@google.com { 15513123Sgabeblack@google.com return _dataReadEvent; 15612841Sgabeblack@google.com } 15712841Sgabeblack@google.com 15813327Sgabeblack@google.com virtual int num_available() const { return _num_available; } 15913327Sgabeblack@google.com virtual int num_free() const { return _num_free; } 16012841Sgabeblack@google.com 16112841Sgabeblack@google.com virtual void 16213123Sgabeblack@google.com print(std::ostream &os=std::cout) const 16312841Sgabeblack@google.com { 16413123Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 16513123Sgabeblack@google.com pos != _entries.end(); pos++) { 16613123Sgabeblack@google.com os << *pos << ::std::endl; 16713123Sgabeblack@google.com } 16812841Sgabeblack@google.com } 16912841Sgabeblack@google.com virtual void 17013143Sgabeblack@google.com dump(std::ostream &os=std::cout) const 17112841Sgabeblack@google.com { 17213143Sgabeblack@google.com os << "name = " << name() << std::endl; 17313143Sgabeblack@google.com int idx = 0; 17413143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 17513143Sgabeblack@google.com pos != _entries.end(); pos++) { 17613143Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 17713143Sgabeblack@google.com } 17812841Sgabeblack@google.com } 17912841Sgabeblack@google.com virtual const char *kind() const { return "sc_fifo"; } 18012841Sgabeblack@google.com 18112841Sgabeblack@google.com protected: 18212841Sgabeblack@google.com virtual void 18312841Sgabeblack@google.com update() 18412841Sgabeblack@google.com { 18513327Sgabeblack@google.com _num_available = _entries.size(); 18613327Sgabeblack@google.com _num_free = _size - _num_available; 18713327Sgabeblack@google.com if (_writesHappened) { 18813327Sgabeblack@google.com _writesHappened = false; 18913123Sgabeblack@google.com _dataWriteEvent.notify(SC_ZERO_TIME); 19013123Sgabeblack@google.com } 19113123Sgabeblack@google.com if (_readsHappened) { 19213123Sgabeblack@google.com _readsHappened = false; 19313123Sgabeblack@google.com _dataReadEvent.notify(SC_ZERO_TIME); 19413123Sgabeblack@google.com } 19512841Sgabeblack@google.com } 19612841Sgabeblack@google.com 19712841Sgabeblack@google.com private: 19812841Sgabeblack@google.com // Disabled 19913407Sgabeblack@google.com sc_fifo(const sc_fifo<T> &) : sc_fifo_in_if<T>(), sc_prim_channel() 20012841Sgabeblack@google.com {} 20112841Sgabeblack@google.com sc_fifo &operator = (const sc_fifo<T> &) { return *this; } 20213123Sgabeblack@google.com 20313303Sgabeblack@google.com sc_gem5::InternalScEvent _dataReadEvent; 20413303Sgabeblack@google.com sc_gem5::InternalScEvent _dataWriteEvent; 20513123Sgabeblack@google.com 20613274Sgabeblack@google.com sc_port_base *_reader; 20713274Sgabeblack@google.com sc_port_base *_writer; 20813274Sgabeblack@google.com 20913123Sgabeblack@google.com int _size; 21013327Sgabeblack@google.com int _num_free; 21113327Sgabeblack@google.com int _num_available; 21213123Sgabeblack@google.com mutable std::list<T> _entries; 21313123Sgabeblack@google.com bool _readsHappened; 21413327Sgabeblack@google.com bool _writesHappened; 21512841Sgabeblack@google.com}; 21612841Sgabeblack@google.com 21712841Sgabeblack@google.comtemplate <class T> 21812841Sgabeblack@google.cominline std::ostream & 21913143Sgabeblack@google.comoperator << (std::ostream &os, const sc_fifo<T> &f) 22012841Sgabeblack@google.com{ 22113143Sgabeblack@google.com f.print(os); 22212841Sgabeblack@google.com return os; 22312841Sgabeblack@google.com} 22412841Sgabeblack@google.com 22512841Sgabeblack@google.com} // namespace sc_core 22612841Sgabeblack@google.com 22712841Sgabeblack@google.com#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 228