sc_fifo.hh revision 13143:87d1097f49b0
111793Sbrandon.potter@amd.com/* 211793Sbrandon.potter@amd.com * Copyright 2018 Google, Inc. 311184Serfan.azarkhish@unibo.it * 411184Serfan.azarkhish@unibo.it * Redistribution and use in source and binary forms, with or without 511184Serfan.azarkhish@unibo.it * modification, are permitted provided that the following conditions are 611184Serfan.azarkhish@unibo.it * met: redistributions of source code must retain the above copyright 711184Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer; 811184Serfan.azarkhish@unibo.it * redistributions in binary form must reproduce the above copyright 911184Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer in the 1011184Serfan.azarkhish@unibo.it * documentation and/or other materials provided with the distribution; 1111184Serfan.azarkhish@unibo.it * neither the name of the copyright holders nor the names of its 1211184Serfan.azarkhish@unibo.it * contributors may be used to endorse or promote products derived from 1311184Serfan.azarkhish@unibo.it * this software without specific prior written permission. 1411184Serfan.azarkhish@unibo.it * 1511184Serfan.azarkhish@unibo.it * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1611184Serfan.azarkhish@unibo.it * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1711184Serfan.azarkhish@unibo.it * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1811184Serfan.azarkhish@unibo.it * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1911184Serfan.azarkhish@unibo.it * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2011184Serfan.azarkhish@unibo.it * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2111184Serfan.azarkhish@unibo.it * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2211184Serfan.azarkhish@unibo.it * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2311184Serfan.azarkhish@unibo.it * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2411184Serfan.azarkhish@unibo.it * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2511184Serfan.azarkhish@unibo.it * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2611184Serfan.azarkhish@unibo.it * 2711184Serfan.azarkhish@unibo.it * Authors: Gabe Black 2811184Serfan.azarkhish@unibo.it */ 2911184Serfan.azarkhish@unibo.it 3011184Serfan.azarkhish@unibo.it#ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 3111184Serfan.azarkhish@unibo.it#define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ 3211184Serfan.azarkhish@unibo.it 3311184Serfan.azarkhish@unibo.it#include <list> 3411184Serfan.azarkhish@unibo.it 3511184Serfan.azarkhish@unibo.it#include "../core/sc_module.hh" // for sc_gen_unique_name 3611184Serfan.azarkhish@unibo.it#include "../core/sc_prim.hh" 3711184Serfan.azarkhish@unibo.it#include "sc_fifo_in_if.hh" 3811184Serfan.azarkhish@unibo.it#include "sc_fifo_out_if.hh" 3911184Serfan.azarkhish@unibo.it#include "warn_unimpl.hh" 4011184Serfan.azarkhish@unibo.it 4111184Serfan.azarkhish@unibo.itnamespace sc_core 4211184Serfan.azarkhish@unibo.it{ 4311184Serfan.azarkhish@unibo.it 4411184Serfan.azarkhish@unibo.itclass sc_port_base; 4511184Serfan.azarkhish@unibo.itclass sc_event; 4611184Serfan.azarkhish@unibo.it 4711184Serfan.azarkhish@unibo.ittemplate <class T> 4811184Serfan.azarkhish@unibo.itclass sc_fifo : public sc_fifo_in_if<T>, 4911184Serfan.azarkhish@unibo.it public sc_fifo_out_if<T>, 5011184Serfan.azarkhish@unibo.it public sc_prim_channel 5111184Serfan.azarkhish@unibo.it{ 5211184Serfan.azarkhish@unibo.it public: 5311184Serfan.azarkhish@unibo.it explicit sc_fifo(int size=16) : 5411184Serfan.azarkhish@unibo.it sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 5511184Serfan.azarkhish@unibo.it sc_prim_channel(sc_gen_unique_name("fifo")), 5611184Serfan.azarkhish@unibo.it _size(size), _readsHappened(false) 5711184Serfan.azarkhish@unibo.it {} 5811184Serfan.azarkhish@unibo.it explicit sc_fifo(const char *name, int size=16) : 5911184Serfan.azarkhish@unibo.it sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), 6011184Serfan.azarkhish@unibo.it sc_prim_channel(name), _size(size), _readsHappened(false) 6111184Serfan.azarkhish@unibo.it {} 6211184Serfan.azarkhish@unibo.it virtual ~sc_fifo() {} 6311184Serfan.azarkhish@unibo.it 6411184Serfan.azarkhish@unibo.it virtual void 6511184Serfan.azarkhish@unibo.it register_port(sc_port_base &, const char *) 6611184Serfan.azarkhish@unibo.it { 6711184Serfan.azarkhish@unibo.it sc_channel_warn_unimpl(__PRETTY_FUNCTION__); 6811184Serfan.azarkhish@unibo.it } 6911184Serfan.azarkhish@unibo.it 7011184Serfan.azarkhish@unibo.it virtual void 7111184Serfan.azarkhish@unibo.it read(T &t) 7211184Serfan.azarkhish@unibo.it { 7311184Serfan.azarkhish@unibo.it while (num_available() == 0) 7411184Serfan.azarkhish@unibo.it sc_core::wait(_dataWriteEvent); 7511184Serfan.azarkhish@unibo.it _readsHappened = true; 7611184Serfan.azarkhish@unibo.it t = _entries.front(); 7711184Serfan.azarkhish@unibo.it _entries.pop_front(); 7811184Serfan.azarkhish@unibo.it request_update(); 7911184Serfan.azarkhish@unibo.it } 8011184Serfan.azarkhish@unibo.it virtual T 8111184Serfan.azarkhish@unibo.it read() 8211184Serfan.azarkhish@unibo.it { 8311184Serfan.azarkhish@unibo.it T t; 8411184Serfan.azarkhish@unibo.it read(t); 8511284Sandreas.hansson@arm.com return t; 8611184Serfan.azarkhish@unibo.it } 8711184Serfan.azarkhish@unibo.it virtual bool 8811184Serfan.azarkhish@unibo.it nb_read(T &t) 8911184Serfan.azarkhish@unibo.it { 9011184Serfan.azarkhish@unibo.it if (num_available()) { 9111184Serfan.azarkhish@unibo.it read(t); 9211184Serfan.azarkhish@unibo.it return true; 9311184Serfan.azarkhish@unibo.it } else { 9411184Serfan.azarkhish@unibo.it return false; 9511184Serfan.azarkhish@unibo.it } 9611184Serfan.azarkhish@unibo.it } 9711184Serfan.azarkhish@unibo.it operator T() { return read(); } 9811184Serfan.azarkhish@unibo.it 9911184Serfan.azarkhish@unibo.it virtual void 10011184Serfan.azarkhish@unibo.it write(const T &t) 10111184Serfan.azarkhish@unibo.it { 10211184Serfan.azarkhish@unibo.it while (num_free() == 0) 10311184Serfan.azarkhish@unibo.it sc_core::wait(_dataReadEvent); 10411184Serfan.azarkhish@unibo.it _pending.emplace_back(t); 10511184Serfan.azarkhish@unibo.it request_update(); 10611184Serfan.azarkhish@unibo.it } 10711184Serfan.azarkhish@unibo.it virtual bool 10811184Serfan.azarkhish@unibo.it nb_write(const T &t) 10911184Serfan.azarkhish@unibo.it { 11011184Serfan.azarkhish@unibo.it if (num_free()) { 11111184Serfan.azarkhish@unibo.it write(t); 11211184Serfan.azarkhish@unibo.it return true; 11311184Serfan.azarkhish@unibo.it } else { 11411184Serfan.azarkhish@unibo.it return false; 11511184Serfan.azarkhish@unibo.it } 11611184Serfan.azarkhish@unibo.it } 11711184Serfan.azarkhish@unibo.it sc_fifo<T> & 11811184Serfan.azarkhish@unibo.it operator = (const T &t) 119 { 120 write(t); 121 return *this; 122 } 123 124 virtual const sc_event & 125 data_written_event() const 126 { 127 return _dataWriteEvent; 128 } 129 virtual const sc_event & 130 data_read_event() const 131 { 132 return _dataReadEvent; 133 } 134 135 virtual int num_available() const { return _entries.size(); } 136 virtual int 137 num_free() const 138 { 139 return _size - _entries.size() - _pending.size(); 140 } 141 142 virtual void 143 print(std::ostream &os=std::cout) const 144 { 145 for (typename ::std::list<T>::iterator pos = _pending.begin(); 146 pos != _pending.end(); pos++) { 147 os << *pos << ::std::endl; 148 } 149 for (typename ::std::list<T>::iterator pos = _entries.begin(); 150 pos != _entries.end(); pos++) { 151 os << *pos << ::std::endl; 152 } 153 } 154 virtual void 155 dump(std::ostream &os=std::cout) const 156 { 157 os << "name = " << name() << std::endl; 158 int idx = 0; 159 for (typename ::std::list<T>::iterator pos = _pending.begin(); 160 pos != _pending.end(); pos++) { 161 os << "value[" << idx++ << "] = " << *pos << ::std::endl; 162 } 163 for (typename ::std::list<T>::iterator pos = _entries.begin(); 164 pos != _entries.end(); pos++) { 165 os << "value[" << idx++ << "] = " << *pos << ::std::endl; 166 } 167 } 168 virtual const char *kind() const { return "sc_fifo"; } 169 170 protected: 171 virtual void 172 update() 173 { 174 if (!_pending.empty()) { 175 _dataWriteEvent.notify(SC_ZERO_TIME); 176 _entries.insert(_entries.end(), _pending.begin(), _pending.end()); 177 _pending.clear(); 178 } 179 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