systemc: Implement the sc_signal_rv channel and ports.
Change-Id: Id1a3fd2ded224bbe94a4a65e0acf34a3547aedcc Reviewed-on: https://gem5-review.googlesource.com/c/12813 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -30,7 +30,10 @@
|
||||
#ifndef __SYSTEMC_EXT_CHANNEL_SC_IN_RV_HH__
|
||||
#define __SYSTEMC_EXT_CHANNEL_SC_IN_RV_HH__
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "sc_in.hh"
|
||||
#include "sc_signal_rv.hh"
|
||||
|
||||
namespace sc_dt
|
||||
{
|
||||
@@ -51,7 +54,18 @@ class sc_in_rv : public sc_in<sc_dt::sc_lv<W>>
|
||||
explicit sc_in_rv(const char *name) : sc_in<sc_dt::sc_lv<W>>(name) {}
|
||||
virtual ~sc_in_rv() {};
|
||||
|
||||
virtual void end_of_elaboration() {}
|
||||
virtual void
|
||||
end_of_elaboration()
|
||||
{
|
||||
sc_in<sc_dt::sc_lv<W> >::end_of_elaboration();
|
||||
if (!dynamic_cast<sc_signal_rv<W> *>(this->get_interface())) {
|
||||
std::ostringstream ss;
|
||||
ss << "port '" << this->name() << "' (" << this->kind() << ")";
|
||||
SC_REPORT_ERROR(
|
||||
"(E117) resolved port not bound to resolved signal",
|
||||
ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *kind() const { return "sc_in_rv"; }
|
||||
|
||||
|
||||
@@ -30,9 +30,12 @@
|
||||
#ifndef __SYSTEMC_EXT_CHANNEL_SC_INOUT_RV_HH__
|
||||
#define __SYSTEMC_EXT_CHANNEL_SC_INOUT_RV_HH__
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "../core/sc_port.hh"
|
||||
#include "sc_signal_in_if.hh"
|
||||
#include "sc_signal_inout_if.hh"
|
||||
#include "sc_signal_rv.hh"
|
||||
#include "warn_unimpl.hh"
|
||||
|
||||
namespace sc_dt
|
||||
@@ -55,37 +58,48 @@ class sc_inout_rv : public sc_inout<sc_dt::sc_lv<W>>
|
||||
virtual ~sc_inout_rv() {}
|
||||
|
||||
sc_inout_rv<W> &
|
||||
operator = (const sc_dt::sc_lv<W> &)
|
||||
operator = (const sc_dt::sc_lv<W> &l)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(l);
|
||||
return *this;
|
||||
}
|
||||
sc_inout_rv<W> &
|
||||
operator = (const sc_signal_in_if<sc_dt::sc_lv<W>> &)
|
||||
operator = (const sc_signal_in_if<sc_dt::sc_lv<W>> &i)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(i.read());
|
||||
return *this;
|
||||
}
|
||||
sc_inout_rv<W> &
|
||||
operator = (const sc_port<sc_signal_in_if<sc_dt::sc_lv<W>>, 1> &)
|
||||
operator = (const sc_port<sc_signal_in_if<sc_dt::sc_lv<W>>, 1> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
sc_inout_rv<W> &
|
||||
operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_lv<W>>, 1> &)
|
||||
operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_lv<W>>, 1> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
sc_inout_rv<W> &
|
||||
operator = (const sc_inout_rv<W> &)
|
||||
operator = (const sc_inout_rv<W> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void end_of_elaboration() {};
|
||||
virtual void
|
||||
end_of_elaboration()
|
||||
{
|
||||
sc_inout<sc_dt::sc_lv<W> >::end_of_elaboration();
|
||||
if (!dynamic_cast<sc_signal_rv<W> *>(this->get_interface())) {
|
||||
std::ostringstream ss;
|
||||
ss << this->name() << " (" << this->kind() << ")";
|
||||
SC_REPORT_ERROR(
|
||||
"(E117) resolved port not bound to resolved signal",
|
||||
ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *kind() const { return "sc_inout_rv"; }
|
||||
};
|
||||
|
||||
@@ -56,33 +56,33 @@ class sc_out_rv : public sc_inout_rv<W>
|
||||
virtual ~sc_out_rv() {};
|
||||
|
||||
sc_out_rv<W> &
|
||||
operator = (const sc_dt::sc_lv<W> &)
|
||||
operator = (const sc_dt::sc_lv<W> &l)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(l);
|
||||
return *this;
|
||||
}
|
||||
sc_out_rv<W> &
|
||||
operator = (const sc_signal_in_if<sc_dt::sc_lv<W>> &)
|
||||
operator = (const sc_signal_in_if<sc_dt::sc_lv<W>> &i)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(i.read());
|
||||
return *this;
|
||||
}
|
||||
sc_out_rv<W> &
|
||||
operator = (const sc_port<sc_signal_in_if<sc_dt::sc_lv<W>>, 1> &)
|
||||
operator = (const sc_port<sc_signal_in_if<sc_dt::sc_lv<W>>, 1> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
sc_out_rv<W> &
|
||||
operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_lv<W>>, 1> &)
|
||||
operator = (const sc_port<sc_signal_inout_if<sc_dt::sc_lv<W>>, 1> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
sc_out_rv<W> &
|
||||
operator = (const sc_out_rv<W> &)
|
||||
operator = (const sc_out_rv<W> &p)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
(*this)->write(p->read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_RV_HH__
|
||||
|
||||
#include "../core/sc_module.hh" // for sc_gen_unique_name
|
||||
#include "../core/scheduler.hh"
|
||||
#include "../dt/bit/sc_logic.hh"
|
||||
#include "../dt/bit/sc_lv.hh"
|
||||
#include "sc_signal.hh"
|
||||
#include "warn_unimpl.hh"
|
||||
|
||||
@@ -66,20 +69,29 @@ class sc_signal_rv : public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
|
||||
}
|
||||
|
||||
virtual void
|
||||
write(const sc_dt::sc_lv<W> &)
|
||||
write(const sc_dt::sc_lv<W> &l)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
::sc_gem5::Process *p = ::sc_gem5::scheduler.current();
|
||||
|
||||
auto it = inputs.find(p);
|
||||
if (it == inputs.end()) {
|
||||
inputs.emplace(p, l);
|
||||
this->request_update();
|
||||
} else if (it->second != l) {
|
||||
it->second = l;
|
||||
this->request_update();
|
||||
}
|
||||
}
|
||||
sc_signal_rv<W> &
|
||||
operator = (const sc_dt::sc_lv<W> &)
|
||||
operator = (const sc_dt::sc_lv<W> &l)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
write(l);
|
||||
return *this;
|
||||
}
|
||||
sc_signal_rv<W> &
|
||||
operator = (const sc_signal_rv<W> &)
|
||||
operator = (const sc_signal_rv<W> &r)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
write(r.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -89,7 +101,28 @@ class sc_signal_rv : public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
|
||||
virtual void
|
||||
update()
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
using sc_dt::Log_0;
|
||||
using sc_dt::Log_1;
|
||||
using sc_dt::Log_Z;
|
||||
using sc_dt::Log_X;
|
||||
static sc_dt::sc_logic_value_t merge_table[4][4] = {
|
||||
{ Log_0, Log_X, Log_0, Log_X },
|
||||
{ Log_X, Log_1, Log_1, Log_X },
|
||||
{ Log_0, Log_1, Log_Z, Log_X },
|
||||
{ Log_X, Log_X, Log_X, Log_X }
|
||||
};
|
||||
|
||||
// Resolve the inputs, and give the result to the underlying
|
||||
// signal class.
|
||||
for (int i = 0; i < W; i++) {
|
||||
sc_dt::sc_logic_value_t bit = Log_Z;
|
||||
for (auto &input: inputs)
|
||||
bit = merge_table[bit][input.second.get_bit(i)];
|
||||
this->m_new_val.set_bit(i, bit);
|
||||
}
|
||||
|
||||
// Ask the signal to update it's value.
|
||||
sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>::update();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -97,6 +130,8 @@ class sc_signal_rv : public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
|
||||
sc_signal_rv(const sc_signal_rv<W> &) :
|
||||
sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>()
|
||||
{}
|
||||
|
||||
std::map<::sc_gem5::Process *, sc_dt::sc_lv<W> > inputs;
|
||||
};
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
Reference in New Issue
Block a user