summaryrefslogtreecommitdiff
path: root/src/systemc/ext/channel/sc_fifo.hh
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-08-27 22:37:27 -0700
committerGabe Black <gabeblack@google.com>2018-10-03 00:11:33 +0000
commite061a36291dfb99b10b6637a80ae3f4da3ac7e0b (patch)
tree883646ae9af02902e71debccb593b2dae1707638 /src/systemc/ext/channel/sc_fifo.hh
parent41b339367c2c858c1dc9fb98931ceb6f3efb5b57 (diff)
downloadgem5-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.hh99
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>