sc_fifo.hh revision 13324
12SN/A/* 210905Sandreas.sandberg@arm.com * Copyright 2018 Google, Inc. 310905Sandreas.sandberg@arm.com * 410905Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 510905Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 610905Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 710905Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 810905Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 910905Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1010905Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1110905Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1210905Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1310905Sandreas.sandberg@arm.com * this software without specific prior written permission. 141762SN/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 * 272SN/A * Authors: Gabe Black 282SN/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#include <string> 352SN/A 362SN/A#include "../core/sc_module.hh" // for sc_gen_unique_name 372SN/A#include "../core/sc_prim.hh" 382SN/A#include "../utils/sc_report_handler.hh" 392665Ssaidi@eecs.umich.edu#include "messages.hh" 402760Sbinkertn@umich.edu#include "sc_fifo_in_if.hh" 412760Sbinkertn@umich.edu#include "sc_fifo_out_if.hh" 422665Ssaidi@eecs.umich.edu 4310905Sandreas.sandberg@arm.comnamespace sc_core 442SN/A{ 452SN/A 462SN/Aclass sc_port_base; 472SN/Aclass sc_event; 482SN/A 492SN/Atemplate <class T> 502SN/Aclass sc_fifo : public sc_fifo_in_if<T>, 512SN/A public sc_fifo_out_if<T>, 522SN/A public sc_prim_channel 532SN/A{ 548229Snate@binkert.org public: 552SN/A explicit sc_fifo(int size=16) : 568229Snate@binkert.org sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 5710905Sandreas.sandberg@arm.com sc_prim_channel(sc_gen_unique_name("fifo")), 584841Ssaidi@eecs.umich.edu _size(size), _readsHappened(false), _reader(NULL), _writer(NULL) 592SN/A {} 6010459SAndreas.Sandberg@ARM.com explicit sc_fifo(const char *name, int size=16) : 616214Snate@binkert.org sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 622SN/A sc_prim_channel(name), _size(size), _readsHappened(false), 632738Sstever@eecs.umich.edu _reader(NULL), _writer(NULL) 64395SN/A {} 6510905Sandreas.sandberg@arm.com virtual ~sc_fifo() {} 664000Ssaidi@eecs.umich.edu 679983Sstever@gmail.com virtual void 682SN/A register_port(sc_port_base &port, const char *iface_type_name) 6910905Sandreas.sandberg@arm.com { 7010905Sandreas.sandberg@arm.com std::string tn(iface_type_name); 7110905Sandreas.sandberg@arm.com if (tn == typeid(sc_fifo_in_if<T>).name() || 729048SAli.Saidi@ARM.com tn == typeid(sc_fifo_blocking_in_if<T>).name()) { 739048SAli.Saidi@ARM.com if (_reader) 749056SAli.Saidi@ARM.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_READER_, ""); 759048SAli.Saidi@ARM.com _reader = &port; 769048SAli.Saidi@ARM.com } else if (tn == typeid(sc_fifo_out_if<T>).name() || 779056SAli.Saidi@ARM.com tn == typeid(sc_fifo_blocking_out_if<T>).name()) { 789048SAli.Saidi@ARM.com if (_writer) 7910861SCurtis.Dunham@arm.com SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_WRITER_, ""); 809048SAli.Saidi@ARM.com _writer = &port; 81217SN/A } else { 8210905Sandreas.sandberg@arm.com SC_REPORT_ERROR(SC_ID_BIND_IF_TO_PORT_, 83217SN/A "sc_fifo<T> port not recognized"); 8410459SAndreas.Sandberg@ARM.com } 8510905Sandreas.sandberg@arm.com } 8610459SAndreas.Sandberg@ARM.com 8710459SAndreas.Sandberg@ARM.com virtual void 8810905Sandreas.sandberg@arm.com read(T &t) 8910459SAndreas.Sandberg@ARM.com { 9010459SAndreas.Sandberg@ARM.com while (num_available() == 0) 91217SN/A sc_core::wait(_dataWriteEvent); 9210905Sandreas.sandberg@arm.com _readsHappened = true; 93217SN/A t = _entries.front(); 9410459SAndreas.Sandberg@ARM.com _entries.pop_front(); 9510905Sandreas.sandberg@arm.com request_update(); 9610459SAndreas.Sandberg@ARM.com } 9710459SAndreas.Sandberg@ARM.com virtual T 9810905Sandreas.sandberg@arm.com read() 9910459SAndreas.Sandberg@ARM.com { 10010459SAndreas.Sandberg@ARM.com T t; 101217SN/A read(t); 10210905Sandreas.sandberg@arm.com return t; 1036820SLisa.Hsu@amd.com } 10410459SAndreas.Sandberg@ARM.com virtual bool 10510905Sandreas.sandberg@arm.com nb_read(T &t) 10610459SAndreas.Sandberg@ARM.com { 10710459SAndreas.Sandberg@ARM.com if (num_available()) { 10810905Sandreas.sandberg@arm.com read(t); 10910459SAndreas.Sandberg@ARM.com return true; 11010459SAndreas.Sandberg@ARM.com } else { 1116820SLisa.Hsu@amd.com return false; 11210905Sandreas.sandberg@arm.com } 1136227Snate@binkert.org } 114217SN/A operator T() { return read(); } 115217SN/A 11610905Sandreas.sandberg@arm.com virtual void 1174841Ssaidi@eecs.umich.edu write(const T &t) 1184841Ssaidi@eecs.umich.edu { 1194841Ssaidi@eecs.umich.edu while (num_free() == 0) 12010905Sandreas.sandberg@arm.com sc_core::wait(_dataReadEvent); 1217948SAli.Saidi@ARM.com _pending.emplace_back(t); 1227948SAli.Saidi@ARM.com request_update(); 1237948SAli.Saidi@ARM.com } 12410905Sandreas.sandberg@arm.com virtual bool 12510905Sandreas.sandberg@arm.com nb_write(const T &t) 126217SN/A { 1274841Ssaidi@eecs.umich.edu if (num_free()) { 12810905Sandreas.sandberg@arm.com write(t); 12910905Sandreas.sandberg@arm.com return true; 1304841Ssaidi@eecs.umich.edu } else { 1317948SAli.Saidi@ARM.com return false; 13210905Sandreas.sandberg@arm.com } 13310905Sandreas.sandberg@arm.com } 1347948SAli.Saidi@ARM.com sc_fifo<T> & 135237SN/A operator = (const T &t) 13610905Sandreas.sandberg@arm.com { 137237SN/A write(t); 1388902Sandreas.hansson@arm.com return *this; 1398902Sandreas.hansson@arm.com } 1408902Sandreas.hansson@arm.com 1418902Sandreas.hansson@arm.com virtual const sc_event & 1428902Sandreas.hansson@arm.com data_written_event() const 1438902Sandreas.hansson@arm.com { 1448902Sandreas.hansson@arm.com return _dataWriteEvent; 1458902Sandreas.hansson@arm.com } 1468902Sandreas.hansson@arm.com virtual const sc_event & 1478902Sandreas.hansson@arm.com data_read_event() const 1488902Sandreas.hansson@arm.com { 149237SN/A return _dataReadEvent; 150217SN/A } 151217SN/A 152217SN/A virtual int num_available() const { return _entries.size(); } 153237SN/A virtual int 15410905Sandreas.sandberg@arm.com num_free() const 155217SN/A { 15610905Sandreas.sandberg@arm.com return _size - _entries.size() - _pending.size(); 15710905Sandreas.sandberg@arm.com } 158217SN/A 159223SN/A virtual void 16010905Sandreas.sandberg@arm.com print(std::ostream &os=std::cout) const 161223SN/A { 1625543Ssaidi@eecs.umich.edu for (typename ::std::list<T>::iterator pos = _pending.begin(); 1635543Ssaidi@eecs.umich.edu pos != _pending.end(); pos++) { 1645543Ssaidi@eecs.umich.edu os << *pos << ::std::endl; 16510905Sandreas.sandberg@arm.com } 16610905Sandreas.sandberg@arm.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 167223SN/A pos != _entries.end(); pos++) { 168223SN/A os << *pos << ::std::endl; 1695543Ssaidi@eecs.umich.edu } 17010905Sandreas.sandberg@arm.com } 171217SN/A virtual void 1725543Ssaidi@eecs.umich.edu dump(std::ostream &os=std::cout) const 17310905Sandreas.sandberg@arm.com { 174237SN/A os << "name = " << name() << std::endl; 17510903Sandreas.sandberg@arm.com int idx = 0; 17610905Sandreas.sandberg@arm.com for (typename ::std::list<T>::iterator pos = _pending.begin(); 17710903Sandreas.sandberg@arm.com pos != _pending.end(); pos++) { 17810903Sandreas.sandberg@arm.com os << "value[" << idx++ << "] = " << *pos << ::std::endl; 17910905Sandreas.sandberg@arm.com } 18010903Sandreas.sandberg@arm.com for (typename ::std::list<T>::iterator pos = _entries.begin(); 18110905Sandreas.sandberg@arm.com pos != _entries.end(); pos++) { 182237SN/A os << "value[" << idx++ << "] = " << *pos << ::std::endl; 1835543Ssaidi@eecs.umich.edu } 1845543Ssaidi@eecs.umich.edu } 1855543Ssaidi@eecs.umich.edu virtual const char *kind() const { return "sc_fifo"; } 18610905Sandreas.sandberg@arm.com 1878902Sandreas.hansson@arm.com protected: 188237SN/A virtual void 189217SN/A update() 1909342SAndreas.Sandberg@arm.com { 1912SN/A if (!_pending.empty()) { 1929342SAndreas.Sandberg@arm.com _dataWriteEvent.notify(SC_ZERO_TIME); 19310905Sandreas.sandberg@arm.com _entries.insert(_entries.end(), _pending.begin(), _pending.end()); 19410905Sandreas.sandberg@arm.com _pending.clear(); 19510905Sandreas.sandberg@arm.com } 19610905Sandreas.sandberg@arm.com if (_readsHappened) { 19710905Sandreas.sandberg@arm.com _readsHappened = false; 19810905Sandreas.sandberg@arm.com _dataReadEvent.notify(SC_ZERO_TIME); 19910905Sandreas.sandberg@arm.com } 20010905Sandreas.sandberg@arm.com } 20110905Sandreas.sandberg@arm.com 20210905Sandreas.sandberg@arm.com private: 20310905Sandreas.sandberg@arm.com // Disabled 20410905Sandreas.sandberg@arm.com sc_fifo(const sc_fifo<T> &) : 20510905Sandreas.sandberg@arm.com sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel() 20610905Sandreas.sandberg@arm.com {} 20710905Sandreas.sandberg@arm.com sc_fifo &operator = (const sc_fifo<T> &) { return *this; } 20810905Sandreas.sandberg@arm.com 20910905Sandreas.sandberg@arm.com sc_gem5::InternalScEvent _dataReadEvent; 21010905Sandreas.sandberg@arm.com sc_gem5::InternalScEvent _dataWriteEvent; 21110905Sandreas.sandberg@arm.com 21210905Sandreas.sandberg@arm.com sc_port_base *_reader; 21310905Sandreas.sandberg@arm.com sc_port_base *_writer; 2149342SAndreas.Sandberg@arm.com 2159342SAndreas.Sandberg@arm.com int _size; 2169342SAndreas.Sandberg@arm.com mutable std::list<T> _entries; 2179342SAndreas.Sandberg@arm.com mutable std::list<T> _pending; 2189342SAndreas.Sandberg@arm.com bool _readsHappened; 2192SN/A}; 220395SN/A 2212SN/Atemplate <class T> 2222SN/Ainline std::ostream & 22310905Sandreas.sandberg@arm.comoperator << (std::ostream &os, const sc_fifo<T> &f) 22410905Sandreas.sandberg@arm.com{ 22510905Sandreas.sandberg@arm.com f.print(os); 22610905Sandreas.sandberg@arm.com return os; 22710905Sandreas.sandberg@arm.com} 22810905Sandreas.sandberg@arm.com 22910905Sandreas.sandberg@arm.com} // namespace sc_core 23010905Sandreas.sandberg@arm.com 23110905Sandreas.sandberg@arm.com#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 23210905Sandreas.sandberg@arm.com