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 | |
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')
-rw-r--r-- | src/systemc/ext/channel/sc_fifo.hh | 99 | ||||
-rw-r--r-- | src/systemc/ext/channel/sc_fifo_in.hh | 66 | ||||
-rw-r--r-- | src/systemc/ext/channel/sc_fifo_out.hh | 57 |
3 files changed, 114 insertions, 108 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> diff --git a/src/systemc/ext/channel/sc_fifo_in.hh b/src/systemc/ext/channel/sc_fifo_in.hh index 0952d77d1..541d1fcaa 100644 --- a/src/systemc/ext/channel/sc_fifo_in.hh +++ b/src/systemc/ext/channel/sc_fifo_in.hh @@ -30,6 +30,7 @@ #ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_IN_HH__ #define __SYSTEMC_EXT_CHANNEL_SC_FIFO_IN_HH__ +#include "../core/sc_event.hh" #include "../core/sc_port.hh" #include "sc_fifo_in_if.hh" #include "warn_unimpl.hh" @@ -44,72 +45,59 @@ template <class T> class sc_fifo_in : public sc_port<sc_fifo_in_if<T>, 0> { public: - sc_fifo_in() : sc_port<sc_fifo_in_if<T>, 0>() {} - explicit sc_fifo_in(const char *name) : sc_port<sc_fifo_in_if<T>, 0>(name) + sc_fifo_in() : sc_port<sc_fifo_in_if<T>, 0>(), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) + {} + explicit sc_fifo_in(const char *name) : + sc_port<sc_fifo_in_if<T>, 0>(name), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} virtual ~sc_fifo_in() {} // Deprecated binding constructors. explicit sc_fifo_in(const sc_fifo_in_if<T> &interface) : - sc_port<sc_fifo_in_if<T>, 0>(interface) + sc_port<sc_fifo_in_if<T>, 0>(interface), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} sc_fifo_in(const char *name, const sc_fifo_in_if<T> &interface) : - sc_port<sc_fifo_in_if<T>, 0>(name, interface) + sc_port<sc_fifo_in_if<T>, 0>(name, interface), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} explicit sc_fifo_in(sc_port_b<sc_fifo_in_if<T> > &parent) : - sc_port<sc_fifo_in_if<T>, 0>(parent) + sc_port<sc_fifo_in_if<T>, 0>(parent), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} sc_fifo_in(const char *name, sc_port_b<sc_fifo_in_if<T> > &parent) : - sc_port<sc_fifo_in_if<T>, 0>(name, parent) + sc_port<sc_fifo_in_if<T>, 0>(name, parent), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} explicit sc_fifo_in(sc_port<sc_fifo_in_if<T>, 0> &parent) : - sc_port<sc_fifo_in_if<T>, 0>(parent) + sc_port<sc_fifo_in_if<T>, 0>(parent), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} sc_fifo_in(const char *name, sc_port<sc_fifo_in_if<T>, 0> &parent) : - sc_port<sc_fifo_in_if<T>, 0>(name, parent) + sc_port<sc_fifo_in_if<T>, 0>(name, parent), + _dataWrittenFinder(*this, &sc_fifo_in_if<T>::data_written_event) {} - void - read(T &) - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - } - T - read() - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(T *)nullptr; - } - bool - nb_read(T &) - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return false; - } + void read(T &t) { (*this)->read(t); } + T read() { return (*this)->read(); } + bool nb_read(T &t) { return (*this)->nb_read(t); } const sc_event & data_written_event() const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(const sc_event *)nullptr; - } - sc_event_finder & - data_written() const - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(sc_event_finder *)nullptr; - } - int - num_available() const - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return 0; + return (*this)->data_written_event(); } + sc_event_finder &data_written() const { return _dataWrittenFinder; } + int num_available() const { return (*this)->num_available(); } virtual const char *kind() const { return "sc_fifo_in"; } private: // Disabled sc_fifo_in(const sc_fifo_in<T> &) : sc_port<sc_fifo_in_if<T>, 0>() {} sc_fifo_in<T> &operator = (const sc_fifo_in<T> &) { return *this; } + + mutable sc_event_finder_t<sc_fifo_in_if<T> > _dataWrittenFinder; }; } // namespace sc_core diff --git a/src/systemc/ext/channel/sc_fifo_out.hh b/src/systemc/ext/channel/sc_fifo_out.hh index af2f6efe5..52840305b 100644 --- a/src/systemc/ext/channel/sc_fifo_out.hh +++ b/src/systemc/ext/channel/sc_fifo_out.hh @@ -44,67 +44,58 @@ template <class T> class sc_fifo_out : public sc_port<sc_fifo_out_if<T>, 0> { public: - sc_fifo_out() : sc_port<sc_fifo_out_if<T>, 0>() {} + sc_fifo_out() : sc_port<sc_fifo_out_if<T>, 0>(), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) + {} explicit sc_fifo_out(const char *name) : - sc_port<sc_fifo_out_if<T>, 0>(name) + sc_port<sc_fifo_out_if<T>, 0>(name), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} virtual ~sc_fifo_out() {} // Deprecated binding constructors. explicit sc_fifo_out(const sc_fifo_out_if<T> &interface) : - sc_port<sc_fifo_out_if<T>, 0>(interface) + sc_port<sc_fifo_out_if<T>, 0>(interface), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} sc_fifo_out(const char *name, const sc_fifo_out_if<T> &interface) : - sc_port<sc_fifo_out_if<T>, 0>(name, interface) + sc_port<sc_fifo_out_if<T>, 0>(name, interface), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} explicit sc_fifo_out(sc_port_b<sc_fifo_out_if<T> > &parent) : - sc_port<sc_fifo_out_if<T>, 0>(parent) + sc_port<sc_fifo_out_if<T>, 0>(parent), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} sc_fifo_out(const char *name, sc_port_b<sc_fifo_out_if<T> > &parent) : - sc_port<sc_fifo_out_if<T>, 0>(name, parent) + sc_port<sc_fifo_out_if<T>, 0>(name, parent), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} explicit sc_fifo_out(sc_port<sc_fifo_out_if<T>, 0> &parent) : - sc_port<sc_fifo_out_if<T>, 0>(parent) + sc_port<sc_fifo_out_if<T>, 0>(parent), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} sc_fifo_out(const char *name, sc_port<sc_fifo_out_if<T>, 0> &parent) : - sc_port<sc_fifo_out_if<T>, 0>(name, parent) + sc_port<sc_fifo_out_if<T>, 0>(name, parent), + _dataReadFinder(*this, &sc_fifo_out_if<T>::data_read_event) {} - void - write(const T &) - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - } - bool - nb_write(const T &) - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return false; - } + void write(const T &t) { (*this)->write(t); } + bool nb_write(const T &t) { return (*this)->nb_write(t); } const sc_event & data_read_event() const { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(const sc_event *)nullptr; - } - sc_event_finder & - data_read() const - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return *(sc_event_finder *)nullptr; - } - int - num_free() const - { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); - return 0; + return (*this)->data_read_event(); } + sc_event_finder &data_read() const { return _dataReadFinder; } + int num_free() const { return (*this)->num_free(); } virtual const char *kind() const { return "sc_fifo_out"; } private: // Disabled sc_fifo_out(const sc_fifo_out<T> &) : sc_port<sc_fifo_out_if<T>, 0>() {} sc_fifo_out<T> &operator = (const sc_fifo_out<T> &) { return *this; } + + mutable sc_event_finder_t<sc_fifo_out_if<T> > _dataReadFinder; }; } // namespace sc_core |