sc_fifo.hh revision 13303
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" 3912841Sgabeblack@google.com#include "sc_fifo_in_if.hh" 4012841Sgabeblack@google.com#include "sc_fifo_out_if.hh" 4112841Sgabeblack@google.com 4212841Sgabeblack@google.comnamespace sc_core 4312841Sgabeblack@google.com{ 4412841Sgabeblack@google.com 4512841Sgabeblack@google.comclass sc_port_base; 4612841Sgabeblack@google.comclass sc_event; 4712841Sgabeblack@google.com 4812841Sgabeblack@google.comtemplate <class T> 4912841Sgabeblack@google.comclass sc_fifo : public sc_fifo_in_if<T>, 5012841Sgabeblack@google.com public sc_fifo_out_if<T>, 5112841Sgabeblack@google.com public sc_prim_channel 5212841Sgabeblack@google.com{ 5312841Sgabeblack@google.com public: 5412841Sgabeblack@google.com explicit sc_fifo(int size=16) : 5512841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 5613123Sgabeblack@google.com sc_prim_channel(sc_gen_unique_name("fifo")), 5713274Sgabeblack@google.com _size(size), _readsHappened(false), _reader(NULL), _writer(NULL) 5812841Sgabeblack@google.com {} 5912841Sgabeblack@google.com explicit sc_fifo(const char *name, int size=16) : 6012841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 6113274Sgabeblack@google.com sc_prim_channel(name), _size(size), _readsHappened(false), 6213274Sgabeblack@google.com _reader(NULL), _writer(NULL) 6312841Sgabeblack@google.com {} 6412841Sgabeblack@google.com virtual ~sc_fifo() {} 6512841Sgabeblack@google.com 6612841Sgabeblack@google.com virtual void 6713274Sgabeblack@google.com register_port(sc_port_base &port, const char *iface_type_name) 6812841Sgabeblack@google.com { 6913274Sgabeblack@google.com std::string tn(iface_type_name); 7013274Sgabeblack@google.com if (tn == typeid(sc_fifo_in_if<T>).name() || 7113274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_in_if<T>).name()) { 7213274Sgabeblack@google.com if (_reader) { 7313274Sgabeblack@google.com SC_REPORT_ERROR( 7413274Sgabeblack@google.com "(E104) sc_fifo<T> cannot have more than one reader", 7513274Sgabeblack@google.com ""); 7613274Sgabeblack@google.com } 7713274Sgabeblack@google.com _reader = &port; 7813274Sgabeblack@google.com } else if (tn == typeid(sc_fifo_out_if<T>).name() || 7913274Sgabeblack@google.com tn == typeid(sc_fifo_blocking_out_if<T>).name()) { 8013274Sgabeblack@google.com if (_writer) { 8113274Sgabeblack@google.com SC_REPORT_ERROR( 8213274Sgabeblack@google.com "(E105) sc_fifo<T> cannot have more than one writer", 8313274Sgabeblack@google.com ""); 8413274Sgabeblack@google.com } 8513274Sgabeblack@google.com _writer = &port; 8613274Sgabeblack@google.com } else { 8713274Sgabeblack@google.com SC_REPORT_ERROR("(E107) bind interface to port failed", 8813274Sgabeblack@google.com "sc_fifo<T> port not recognized"); 8913274Sgabeblack@google.com } 9012841Sgabeblack@google.com } 9112841Sgabeblack@google.com 9212841Sgabeblack@google.com virtual void 9313123Sgabeblack@google.com read(T &t) 9412841Sgabeblack@google.com { 9513123Sgabeblack@google.com while (num_available() == 0) 9613123Sgabeblack@google.com sc_core::wait(_dataWriteEvent); 9713123Sgabeblack@google.com _readsHappened = true; 9813123Sgabeblack@google.com t = _entries.front(); 9913123Sgabeblack@google.com _entries.pop_front(); 10013123Sgabeblack@google.com request_update(); 10112841Sgabeblack@google.com } 10212841Sgabeblack@google.com virtual T 10312841Sgabeblack@google.com read() 10412841Sgabeblack@google.com { 10513123Sgabeblack@google.com T t; 10613123Sgabeblack@google.com read(t); 10713123Sgabeblack@google.com return t; 10812841Sgabeblack@google.com } 10912841Sgabeblack@google.com virtual bool 11013123Sgabeblack@google.com nb_read(T &t) 11112841Sgabeblack@google.com { 11213123Sgabeblack@google.com if (num_available()) { 11313123Sgabeblack@google.com read(t); 11413123Sgabeblack@google.com return true; 11513123Sgabeblack@google.com } else { 11613123Sgabeblack@google.com return false; 11713123Sgabeblack@google.com } 11812841Sgabeblack@google.com } 11913123Sgabeblack@google.com operator T() { return read(); } 12012841Sgabeblack@google.com 12112841Sgabeblack@google.com virtual void 12213123Sgabeblack@google.com write(const T &t) 12312841Sgabeblack@google.com { 12413123Sgabeblack@google.com while (num_free() == 0) 12513123Sgabeblack@google.com sc_core::wait(_dataReadEvent); 12613123Sgabeblack@google.com _pending.emplace_back(t); 12713123Sgabeblack@google.com request_update(); 12812841Sgabeblack@google.com } 12912841Sgabeblack@google.com virtual bool 13013123Sgabeblack@google.com nb_write(const T &t) 13112841Sgabeblack@google.com { 13213123Sgabeblack@google.com if (num_free()) { 13313123Sgabeblack@google.com write(t); 13413123Sgabeblack@google.com return true; 13513123Sgabeblack@google.com } else { 13613123Sgabeblack@google.com return false; 13713123Sgabeblack@google.com } 13812841Sgabeblack@google.com } 13912841Sgabeblack@google.com sc_fifo<T> & 14013123Sgabeblack@google.com operator = (const T &t) 14112841Sgabeblack@google.com { 14213123Sgabeblack@google.com write(t); 14312841Sgabeblack@google.com return *this; 14412841Sgabeblack@google.com } 14512841Sgabeblack@google.com 14612841Sgabeblack@google.com virtual const sc_event & 14712853Sgabeblack@google.com data_written_event() const 14812841Sgabeblack@google.com { 14913123Sgabeblack@google.com return _dataWriteEvent; 15012841Sgabeblack@google.com } 15112841Sgabeblack@google.com virtual const sc_event & 15212841Sgabeblack@google.com data_read_event() const 15312841Sgabeblack@google.com { 15413123Sgabeblack@google.com return _dataReadEvent; 15512841Sgabeblack@google.com } 15612841Sgabeblack@google.com 15713123Sgabeblack@google.com virtual int num_available() const { return _entries.size(); } 15812841Sgabeblack@google.com virtual int 15912841Sgabeblack@google.com num_free() const 16012841Sgabeblack@google.com { 16113123Sgabeblack@google.com return _size - _entries.size() - _pending.size(); 16212841Sgabeblack@google.com } 16312841Sgabeblack@google.com 16412841Sgabeblack@google.com virtual void 16513123Sgabeblack@google.com print(std::ostream &os=std::cout) const 16612841Sgabeblack@google.com { 16713143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 16813143Sgabeblack@google.com pos != _pending.end(); pos++) { 16913143Sgabeblack@google.com os << *pos << ::std::endl; 17013143Sgabeblack@google.com } 17113123Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 17213123Sgabeblack@google.com pos != _entries.end(); pos++) { 17313123Sgabeblack@google.com os << *pos << ::std::endl; 17413123Sgabeblack@google.com } 17512841Sgabeblack@google.com } 17612841Sgabeblack@google.com virtual void 17713143Sgabeblack@google.com dump(std::ostream &os=std::cout) const 17812841Sgabeblack@google.com { 17913143Sgabeblack@google.com os << "name = " << name() << std::endl; 18013143Sgabeblack@google.com int idx = 0; 18113143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 18213143Sgabeblack@google.com pos != _pending.end(); pos++) { 18313143Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 18413143Sgabeblack@google.com } 18513143Sgabeblack@google.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 18613143Sgabeblack@google.com pos != _entries.end(); pos++) { 18713143Sgabeblack@google.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 18813143Sgabeblack@google.com } 18912841Sgabeblack@google.com } 19012841Sgabeblack@google.com virtual const char *kind() const { return "sc_fifo"; } 19112841Sgabeblack@google.com 19212841Sgabeblack@google.com protected: 19312841Sgabeblack@google.com virtual void 19412841Sgabeblack@google.com update() 19512841Sgabeblack@google.com { 19613123Sgabeblack@google.com if (!_pending.empty()) { 19713123Sgabeblack@google.com _dataWriteEvent.notify(SC_ZERO_TIME); 19813123Sgabeblack@google.com _entries.insert(_entries.end(), _pending.begin(), _pending.end()); 19913123Sgabeblack@google.com _pending.clear(); 20013123Sgabeblack@google.com } 20113123Sgabeblack@google.com if (_readsHappened) { 20213123Sgabeblack@google.com _readsHappened = false; 20313123Sgabeblack@google.com _dataReadEvent.notify(SC_ZERO_TIME); 20413123Sgabeblack@google.com } 20512841Sgabeblack@google.com } 20612841Sgabeblack@google.com 20712841Sgabeblack@google.com private: 20812841Sgabeblack@google.com // Disabled 20912841Sgabeblack@google.com sc_fifo(const sc_fifo<T> &) : 21012841Sgabeblack@google.com sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel() 21112841Sgabeblack@google.com {} 21212841Sgabeblack@google.com sc_fifo &operator = (const sc_fifo<T> &) { return *this; } 21313123Sgabeblack@google.com 21413303Sgabeblack@google.com sc_gem5::InternalScEvent _dataReadEvent; 21513303Sgabeblack@google.com sc_gem5::InternalScEvent _dataWriteEvent; 21613123Sgabeblack@google.com 21713274Sgabeblack@google.com sc_port_base *_reader; 21813274Sgabeblack@google.com sc_port_base *_writer; 21913274Sgabeblack@google.com 22013123Sgabeblack@google.com int _size; 22113123Sgabeblack@google.com mutable std::list<T> _entries; 22213123Sgabeblack@google.com mutable std::list<T> _pending; 22313123Sgabeblack@google.com bool _readsHappened; 22412841Sgabeblack@google.com}; 22512841Sgabeblack@google.com 22612841Sgabeblack@google.comtemplate <class T> 22712841Sgabeblack@google.cominline std::ostream & 22813143Sgabeblack@google.comoperator << (std::ostream &os, const sc_fifo<T> &f) 22912841Sgabeblack@google.com{ 23013143Sgabeblack@google.com f.print(os); 23112841Sgabeblack@google.com return os; 23212841Sgabeblack@google.com} 23312841Sgabeblack@google.com 23412841Sgabeblack@google.com} // namespace sc_core 23512841Sgabeblack@google.com 23612841Sgabeblack@google.com#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 237