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>
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user