summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-10-08 22:39:36 -0700
committerGabe Black <gabeblack@google.com>2018-10-16 01:14:55 +0000
commitae1ecec85aa090b90c09cc126a32b8dfa810c94d (patch)
treed3e4e3e6872d7913755af74e3a6a739ef73b9ffc /src
parent70f52c3561012bd9ba01b3f123e4807d2f5da3d4 (diff)
downloadgem5-ae1ecec85aa090b90c09cc126a32b8dfa810c94d.tar.xz
systemc: Fix accounting in the sc_fifo class.
Reads shouldn't free up space until an update happens. Change-Id: I18e1601c27b44643f103c86f04b1fa2c23baf1e8 Reviewed-on: https://gem5-review.googlesource.com/c/13333 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/systemc/ext/channel/sc_fifo.hh39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/systemc/ext/channel/sc_fifo.hh b/src/systemc/ext/channel/sc_fifo.hh
index 0c83f6692..ee7872a26 100644
--- a/src/systemc/ext/channel/sc_fifo.hh
+++ b/src/systemc/ext/channel/sc_fifo.hh
@@ -55,11 +55,14 @@ class sc_fifo : public sc_fifo_in_if<T>,
explicit sc_fifo(int size=16) :
sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
sc_prim_channel(sc_gen_unique_name("fifo")),
- _size(size), _readsHappened(false), _reader(NULL), _writer(NULL)
+ _size(size), _num_free(size), _num_available(0),
+ _readsHappened(false), _writesHappened(false),
+ _reader(NULL), _writer(NULL)
{}
explicit sc_fifo(const char *name, int size=16) :
sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
- sc_prim_channel(name), _size(size), _readsHappened(false),
+ sc_prim_channel(name), _size(size), _num_free(size),
+ _num_available(0), _readsHappened(false), _writesHappened(false),
_reader(NULL), _writer(NULL)
{}
virtual ~sc_fifo() {}
@@ -92,6 +95,7 @@ class sc_fifo : public sc_fifo_in_if<T>,
_readsHappened = true;
t = _entries.front();
_entries.pop_front();
+ _num_available--;
request_update();
}
virtual T
@@ -118,7 +122,9 @@ class sc_fifo : public sc_fifo_in_if<T>,
{
while (num_free() == 0)
sc_core::wait(_dataReadEvent);
- _pending.emplace_back(t);
+ _writesHappened = true;
+ _entries.emplace_back(t);
+ _num_free--;
request_update();
}
virtual bool
@@ -149,20 +155,12 @@ class sc_fifo : public sc_fifo_in_if<T>,
return _dataReadEvent;
}
- virtual int num_available() const { return _entries.size(); }
- virtual int
- num_free() const
- {
- return _size - _entries.size() - _pending.size();
- }
+ virtual int num_available() const { return _num_available; }
+ virtual int num_free() const { return _num_free; }
virtual void
print(std::ostream &os=std::cout) const
{
- for (typename ::std::list<T>::iterator pos = _pending.begin();
- pos != _pending.end(); pos++) {
- os << *pos << ::std::endl;
- }
for (typename ::std::list<T>::iterator pos = _entries.begin();
pos != _entries.end(); pos++) {
os << *pos << ::std::endl;
@@ -173,10 +171,6 @@ class sc_fifo : public sc_fifo_in_if<T>,
{
os << "name = " << name() << std::endl;
int idx = 0;
- for (typename ::std::list<T>::iterator pos = _pending.begin();
- pos != _pending.end(); pos++) {
- os << "value[" << idx++ << "] = " << *pos << ::std::endl;
- }
for (typename ::std::list<T>::iterator pos = _entries.begin();
pos != _entries.end(); pos++) {
os << "value[" << idx++ << "] = " << *pos << ::std::endl;
@@ -188,10 +182,11 @@ class sc_fifo : public sc_fifo_in_if<T>,
virtual void
update()
{
- if (!_pending.empty()) {
+ _num_available = _entries.size();
+ _num_free = _size - _num_available;
+ if (_writesHappened) {
+ _writesHappened = false;
_dataWriteEvent.notify(SC_ZERO_TIME);
- _entries.insert(_entries.end(), _pending.begin(), _pending.end());
- _pending.clear();
}
if (_readsHappened) {
_readsHappened = false;
@@ -213,9 +208,11 @@ class sc_fifo : public sc_fifo_in_if<T>,
sc_port_base *_writer;
int _size;
+ int _num_free;
+ int _num_available;
mutable std::list<T> _entries;
- mutable std::list<T> _pending;
bool _readsHappened;
+ bool _writesHappened;
};
template <class T>