From e061a36291dfb99b10b6637a80ae3f4da3ac7e0b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Aug 2018 22:37:27 -0700 Subject: [PATCH] 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 Maintainer: Gabe Black --- src/systemc/ext/channel/sc_fifo.hh | 99 ++++++++++++++++---------- src/systemc/ext/channel/sc_fifo_in.hh | 66 +++++++---------- 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 + #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, public: explicit sc_fifo(int size=16) : sc_fifo_in_if(), sc_fifo_out_if(), - 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(), sc_fifo_out_if(), - 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, } 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 & - 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::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, 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, sc_fifo_in_if(), sc_fifo_in_if(), sc_prim_channel() {} sc_fifo &operator = (const sc_fifo &) { return *this; } + + sc_event _dataReadEvent; + sc_event _dataWriteEvent; + + int _size; + mutable std::list _entries; + mutable std::list _pending; + bool _readsHappened; }; template 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 sc_fifo_in : public sc_port, 0> { public: - sc_fifo_in() : sc_port, 0>() {} - explicit sc_fifo_in(const char *name) : sc_port, 0>(name) + sc_fifo_in() : sc_port, 0>(), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) + {} + explicit sc_fifo_in(const char *name) : + sc_port, 0>(name), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} virtual ~sc_fifo_in() {} // Deprecated binding constructors. explicit sc_fifo_in(const sc_fifo_in_if &interface) : - sc_port, 0>(interface) + sc_port, 0>(interface), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} sc_fifo_in(const char *name, const sc_fifo_in_if &interface) : - sc_port, 0>(name, interface) + sc_port, 0>(name, interface), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} explicit sc_fifo_in(sc_port_b > &parent) : - sc_port, 0>(parent) + sc_port, 0>(parent), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} sc_fifo_in(const char *name, sc_port_b > &parent) : - sc_port, 0>(name, parent) + sc_port, 0>(name, parent), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} explicit sc_fifo_in(sc_port, 0> &parent) : - sc_port, 0>(parent) + sc_port, 0>(parent), + _dataWrittenFinder(*this, &sc_fifo_in_if::data_written_event) {} sc_fifo_in(const char *name, sc_port, 0> &parent) : - sc_port, 0>(name, parent) + sc_port, 0>(name, parent), + _dataWrittenFinder(*this, &sc_fifo_in_if::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 &) : sc_port, 0>() {} sc_fifo_in &operator = (const sc_fifo_in &) { return *this; } + + mutable sc_event_finder_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 sc_fifo_out : public sc_port, 0> { public: - sc_fifo_out() : sc_port, 0>() {} + sc_fifo_out() : sc_port, 0>(), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) + {} explicit sc_fifo_out(const char *name) : - sc_port, 0>(name) + sc_port, 0>(name), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} virtual ~sc_fifo_out() {} // Deprecated binding constructors. explicit sc_fifo_out(const sc_fifo_out_if &interface) : - sc_port, 0>(interface) + sc_port, 0>(interface), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} sc_fifo_out(const char *name, const sc_fifo_out_if &interface) : - sc_port, 0>(name, interface) + sc_port, 0>(name, interface), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} explicit sc_fifo_out(sc_port_b > &parent) : - sc_port, 0>(parent) + sc_port, 0>(parent), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} sc_fifo_out(const char *name, sc_port_b > &parent) : - sc_port, 0>(name, parent) + sc_port, 0>(name, parent), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} explicit sc_fifo_out(sc_port, 0> &parent) : - sc_port, 0>(parent) + sc_port, 0>(parent), + _dataReadFinder(*this, &sc_fifo_out_if::data_read_event) {} sc_fifo_out(const char *name, sc_port, 0> &parent) : - sc_port, 0>(name, parent) + sc_port, 0>(name, parent), + _dataReadFinder(*this, &sc_fifo_out_if::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 &) : sc_port, 0>() {} sc_fifo_out &operator = (const sc_fifo_out &) { return *this; } + + mutable sc_event_finder_t > _dataReadFinder; }; } // namespace sc_core -- 2.30.2