diff options
author | Gabe Black <gabeblack@google.com> | 2018-08-27 22:37:27 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-10-03 00:11:33 +0000 |
commit | e061a36291dfb99b10b6637a80ae3f4da3ac7e0b (patch) | |
tree | 883646ae9af02902e71debccb593b2dae1707638 /src/systemc/ext/channel/sc_fifo.hh | |
parent | 41b339367c2c858c1dc9fb98931ceb6f3efb5b57 (diff) | |
download | gem5-e061a36291dfb99b10b6637a80ae3f4da3ac7e0b.tar.xz |
systemc: Implement most of sc_fifo and its interfaces.
There are still some bugs since the output of the tests don't all
match, but more tests pass and fewer abort.
Change-Id: I37f84d65c4a8a43357c98282096e39b9401fc1dd
Reviewed-on: https://gem5-review.googlesource.com/c/12275
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/ext/channel/sc_fifo.hh')
-rw-r--r-- | src/systemc/ext/channel/sc_fifo.hh | 99 |
1 files changed, 63 insertions, 36 deletions
diff --git a/src/systemc/ext/channel/sc_fifo.hh b/src/systemc/ext/channel/sc_fifo.hh index 8cf2124b7..4fe704613 100644 --- a/src/systemc/ext/channel/sc_fifo.hh +++ b/src/systemc/ext/channel/sc_fifo.hh @@ -30,6 +30,8 @@ #ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ #define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__ +#include <list> + #include "../core/sc_module.hh" // for sc_gen_unique_name #include "../core/sc_prim.hh" #include "sc_fifo_in_if.hh" @@ -50,11 +52,12 @@ class sc_fifo : public sc_fifo_in_if<T>, public: explicit sc_fifo(int size=16) : sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), - sc_prim_channel(sc_gen_unique_name("fifo")) + sc_prim_channel(sc_gen_unique_name("fifo")), + _size(size), _readsHappened(false) {} explicit sc_fifo(const char *name, int size=16) : sc_fifo_in_if<T>(), sc_fifo_out_if<T>(), - sc_prim_channel(name) + sc_prim_channel(name), _size(size), _readsHappened(false) {} virtual ~sc_fifo() {} @@ -65,76 +68,84 @@ class sc_fifo : public sc_fifo_in_if<T>, } virtual void - read(T &) + read(T &t) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + while (num_available() == 0) + sc_core::wait(_dataWriteEvent); + _readsHappened = true; + t = _entries.front(); + _entries.pop_front(); + request_update(); } virtual T read() { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(T *)nullptr; + T t; + read(t); + return t; } virtual bool - nb_read(T &) + nb_read(T &t) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return false; - } - operator T() - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(T *)nullptr; + if (num_available()) { + read(t); + return true; + } else { + return false; + } } + operator T() { return read(); } virtual void - write(const T &) + write(const T &t) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + while (num_free() == 0) + sc_core::wait(_dataReadEvent); + _pending.emplace_back(t); + request_update(); } virtual bool - nb_write(const T&) + nb_write(const T &t) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return false; + if (num_free()) { + write(t); + return true; + } else { + return false; + } } sc_fifo<T> & - operator = (const T &) + operator = (const T &t) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + write(t); return *this; } virtual const sc_event & data_written_event() const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(const sc_event *)nullptr; + return _dataWriteEvent; } virtual const sc_event & data_read_event() const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(const sc_event *)nullptr; + return _dataReadEvent; } - virtual int - num_available() const - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return 0; - } + virtual int num_available() const { return _entries.size(); } virtual int num_free() const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return 0; + return _size - _entries.size() - _pending.size(); } virtual void - print(std::ostream & =std::cout) const + print(std::ostream &os=std::cout) const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + for (typename ::std::list<T>::iterator pos = _entries.begin(); + pos != _entries.end(); pos++) { + os << *pos << ::std::endl; + } } virtual void dump(std::ostream & =std::cout) const @@ -147,7 +158,15 @@ class sc_fifo : public sc_fifo_in_if<T>, virtual void update() { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + if (!_pending.empty()) { + _dataWriteEvent.notify(SC_ZERO_TIME); + _entries.insert(_entries.end(), _pending.begin(), _pending.end()); + _pending.clear(); + } + if (_readsHappened) { + _readsHappened = false; + _dataReadEvent.notify(SC_ZERO_TIME); + } } private: @@ -156,6 +175,14 @@ class sc_fifo : public sc_fifo_in_if<T>, sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel() {} sc_fifo &operator = (const sc_fifo<T> &) { return *this; } + + sc_event _dataReadEvent; + sc_event _dataWriteEvent; + + int _size; + mutable std::list<T> _entries; + mutable std::list<T> _pending; + bool _readsHappened; }; template <class T> |