sc_fifo.hh revision 13324
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")), 5813274Sgabeblack@google.com _size(size), _readsHappened(false), _reader(NULL), _writer(NULL) 5912841Sgabeblack@google.com {} 6012841Sgabeblack@google.com explicit sc_fifo(const char *name, int size=16) : 6112841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 6213274Sgabeblack@google.com sc_prim_channel(name), _size(size), _readsHappened(false), 6313274Sgabeblack@google.com _reader(NULL), _writer(NULL) 6412841Sgabeblack@google.com {} 6512841Sgabeblack@google.com virtual ~sc_fifo() {} 6612841Sgabeblack@google.com 6712841Sgabeblack@google.com virtual void 6813274Sgabeblack@google.com register_port(sc_port_base &port, const char *iface_type_name) 6912841Sgabeblack@google.com { 7013274Sgabeblack@google.com std::string tn(iface_type_name); 7113274Sgabeblack@google.com if (tn == typeid(sc_fifo_in_if<T>).name() || 7213274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_in_if<T>).name()) { 7313324Sgabeblack@google.com if (_reader) 7413324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_READER_, ""); 7513274Sgabeblack@google.com _reader = &port; 7613274Sgabeblack@google.com } else if (tn == typeid(sc_fifo_out_if<T>).name() || 7713274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_out_if<T>).name()) { 7813324Sgabeblack@google.com if (_writer) 7913324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_WRITER_, ""); 8013274Sgabeblack@google.com _writer = &port; 8113274Sgabeblack@google.com } else { 8213324Sgabeblack@google.com SC_REPORT_ERROR(SC_ID_BIND_IF_TO_PORT_, 8313274Sgabeblack@google.com "sc_fifo<T> port not recognized"); 8413274Sgabeblack@google.com } 8512841Sgabeblack@google.com } 8612841Sgabeblack@google.com 8712841Sgabeblack@google.com virtual void 8813123Sgabeblack@google.com read(T &t) 8912841Sgabeblack@google.com { 9013123Sgabeblack@google.com while (num_available() == 0) 9113123Sgabeblack@google.com sc_core::wait(_dataWriteEvent); 9213123Sgabeblack@google.com _readsHappened = true; 9313123Sgabeblack@google.com t = _entries.front(); 9413123Sgabeblack@google.com _entries.pop_front(); 9513123Sgabeblack@google.com request_update(); 9612841Sgabeblack@google.com } 9712841Sgabeblack@google.com virtual T 9812841Sgabeblack@google.com read() 9912841Sgabeblack@google.com { 10013123Sgabeblack@google.com T t; 10113123Sgabeblack@google.com read(t); 10213123Sgabeblack@google.com return t; 10312841Sgabeblack@google.com } 10412841Sgabeblack@google.com virtual bool 10513123Sgabeblack@google.com nb_read(T &t) 10612841Sgabeblack@google.com { 10713123Sgabeblack@google.com if (num_available()) { 10813123Sgabeblack@google.com read(t); 10913123Sgabeblack@google.com return true; 11013123Sgabeblack@google.com } else { 11113123Sgabeblack@google.com return false; 11213123Sgabeblack@google.com } 11312841Sgabeblack@google.com } 11413123Sgabeblack@google.com operator T() { return read(); } 11512841Sgabeblack@google.com 11612841Sgabeblack@google.com virtual void 11713123Sgabeblack@google.com write(const T &t) 11812841Sgabeblack@google.com { 11913123Sgabeblack@google.com while (num_free() == 0) 12013123Sgabeblack@google.com sc_core::wait(_dataReadEvent); 12113123Sgabeblack@google.com _pending.emplace_back(t); 12213123Sgabeblack@google.com request_update(); 12312841Sgabeblack@google.com } 12412841Sgabeblack@google.com virtual bool 12513123Sgabeblack@google.com nb_write(const T &t) 12612841Sgabeblack@google.com { 12713123Sgabeblack@google.com if (num_free()) { 12813123Sgabeblack@google.com write(t); 12913123Sgabeblack@google.com return true; 13013123Sgabeblack@google.com } else { 13113123Sgabeblack@google.com return false; 13213123Sgabeblack@google.com } 13312841Sgabeblack@google.com } 13412841Sgabeblack@google.com sc_fifo<T> & 13513123Sgabeblack@google.com operator = (const T &t) 13612841Sgabeblack@google.com { 13713123Sgabeblack@google.com write(t); 13812841Sgabeblack@google.com return *this; 13912841Sgabeblack@google.com } 14012841Sgabeblack@google.com 14112841Sgabeblack@google.com virtual const sc_event & 14212853Sgabeblack@google.com data_written_event() const 14312841Sgabeblack@google.com { 14413123Sgabeblack@google.com return _dataWriteEvent; 14512841Sgabeblack@google.com } 14612841Sgabeblack@google.com virtual const sc_event & 14712841Sgabeblack@google.com data_read_event() const 14812841Sgabeblack@google.com { 14913123Sgabeblack@google.com return _dataReadEvent; 15012841Sgabeblack@google.com } 15112841Sgabeblack@google.com 15213123Sgabeblack@google.com virtual int num_available() const { return _entries.size(); } 15312841Sgabeblack@google.com virtual int 15412841Sgabeblack@google.com num_free() const 15512841Sgabeblack@google.com { 15613123Sgabeblack@google.com return _size - _entries.size() - _pending.size(); 15712841Sgabeblack@google.com } 15812841Sgabeblack@google.com 15912841Sgabeblack@google.com virtual void 16013123Sgabeblack@google.com print(std::ostream &os=std::cout) const 16112841Sgabeblack@google.com { 16213143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 16313143Sgabeblack@google.com pos != _pending.end(); pos++) { 16413143Sgabeblack@google.com os << *pos << ::std::endl; 16513143Sgabeblack@google.com } 16613123Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 16713123Sgabeblack@google.com pos != _entries.end(); pos++) { 16813123Sgabeblack@google.com os << *pos << ::std::endl; 16913123Sgabeblack@google.com } 17012841Sgabeblack@google.com } 17112841Sgabeblack@google.com virtual void 17213143Sgabeblack@google.com dump(std::ostream &os=std::cout) const 17312841Sgabeblack@google.com { 17413143Sgabeblack@google.com os << "name = " << name() << std::endl; 17513143Sgabeblack@google.com int idx = 0; 17613143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 17713143Sgabeblack@google.com pos != _pending.end(); pos++) { 17813143Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 17913143Sgabeblack@google.com } 18013143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 18113143Sgabeblack@google.com pos != _entries.end(); pos++) { 18213143Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 18313143Sgabeblack@google.com } 18412841Sgabeblack@google.com } 18512841Sgabeblack@google.com virtual const char *kind() const { return "sc_fifo"; } 18612841Sgabeblack@google.com 18712841Sgabeblack@google.com protected: 18812841Sgabeblack@google.com virtual void 18912841Sgabeblack@google.com update() 19012841Sgabeblack@google.com { 19113123Sgabeblack@google.com if (!_pending.empty()) { 19213123Sgabeblack@google.com _dataWriteEvent.notify(SC_ZERO_TIME); 19313123Sgabeblack@google.com _entries.insert(_entries.end(), _pending.begin(), _pending.end()); 19413123Sgabeblack@google.com _pending.clear(); 19513123Sgabeblack@google.com } 19613123Sgabeblack@google.com if (_readsHappened) { 19713123Sgabeblack@google.com _readsHappened = false; 19813123Sgabeblack@google.com _dataReadEvent.notify(SC_ZERO_TIME); 19913123Sgabeblack@google.com } 20012841Sgabeblack@google.com } 20112841Sgabeblack@google.com 20212841Sgabeblack@google.com private: 20312841Sgabeblack@google.com // Disabled 20412841Sgabeblack@google.com sc_fifo(const sc_fifo<T> &) : 20512841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel() 20612841Sgabeblack@google.com {} 20712841Sgabeblack@google.com sc_fifo &operator = (const sc_fifo<T> &) { return *this; } 20813123Sgabeblack@google.com 20913303Sgabeblack@google.com sc_gem5::InternalScEvent _dataReadEvent; 21013303Sgabeblack@google.com sc_gem5::InternalScEvent _dataWriteEvent; 21113123Sgabeblack@google.com 21213274Sgabeblack@google.com sc_port_base *_reader; 21313274Sgabeblack@google.com sc_port_base *_writer; 21413274Sgabeblack@google.com 21513123Sgabeblack@google.com int _size; 21613123Sgabeblack@google.com mutable std::list<T> _entries; 21713123Sgabeblack@google.com mutable std::list<T> _pending; 21813123Sgabeblack@google.com bool _readsHappened; 21912841Sgabeblack@google.com}; 22012841Sgabeblack@google.com 22112841Sgabeblack@google.comtemplate <class T> 22212841Sgabeblack@google.cominline std::ostream & 22313143Sgabeblack@google.comoperator << (std::ostream &os, const sc_fifo<T> &f) 22412841Sgabeblack@google.com{ 22513143Sgabeblack@google.com f.print(os); 22612841Sgabeblack@google.com return os; 22712841Sgabeblack@google.com} 22812841Sgabeblack@google.com 22912841Sgabeblack@google.com} // namespace sc_core 23012841Sgabeblack@google.com 23112841Sgabeblack@google.com#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 232