summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-09-15 15:24:28 -0700
committerGabe Black <gabeblack@google.com>2018-10-09 21:52:42 +0000
commitdd017903991f51e1fa8df8dbc21cbb4a1501c1c1 (patch)
tree39f7e475414aaeef75dbb2bb2d9f7f7b30ff367f
parentfad9488643dbf09e4d99b89b6b775fd6f1b24ba6 (diff)
downloadgem5-dd017903991f51e1fa8df8dbc21cbb4a1501c1c1.tar.xz
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>
-rw-r--r--src/systemc/ext/channel/sc_in_rv.hh16
-rw-r--r--src/systemc/ext/channel/sc_inout_rv.hh36
-rw-r--r--src/systemc/ext/channel/sc_out_rv.hh20
-rw-r--r--src/systemc/ext/channel/sc_signal_rv.hh49
-rw-r--r--src/systemc/tests/systemc/communication/sc_signal_rv/test02/expected_returncode1
-rw-r--r--src/systemc/tests/systemc/communication/sc_signal_rv/test03/expected_returncode1
6 files changed, 94 insertions, 29 deletions
diff --git a/src/systemc/ext/channel/sc_in_rv.hh b/src/systemc/ext/channel/sc_in_rv.hh
index eca2c0c7e..278b95864 100644
--- a/src/systemc/ext/channel/sc_in_rv.hh
+++ b/src/systemc/ext/channel/sc_in_rv.hh
@@ -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"; }
diff --git a/src/systemc/ext/channel/sc_inout_rv.hh b/src/systemc/ext/channel/sc_inout_rv.hh
index f231d9311..5ff9d105e 100644
--- a/src/systemc/ext/channel/sc_inout_rv.hh
+++ b/src/systemc/ext/channel/sc_inout_rv.hh
@@ -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"; }
};
diff --git a/src/systemc/ext/channel/sc_out_rv.hh b/src/systemc/ext/channel/sc_out_rv.hh
index af5b05526..ace1f05c5 100644
--- a/src/systemc/ext/channel/sc_out_rv.hh
+++ b/src/systemc/ext/channel/sc_out_rv.hh
@@ -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;
}
diff --git a/src/systemc/ext/channel/sc_signal_rv.hh b/src/systemc/ext/channel/sc_signal_rv.hh
index 723c2b45d..d333da052 100644
--- a/src/systemc/ext/channel/sc_signal_rv.hh
+++ b/src/systemc/ext/channel/sc_signal_rv.hh
@@ -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
diff --git a/src/systemc/tests/systemc/communication/sc_signal_rv/test02/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal_rv/test02/expected_returncode
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/src/systemc/tests/systemc/communication/sc_signal_rv/test02/expected_returncode
@@ -0,0 +1 @@
+1
diff --git a/src/systemc/tests/systemc/communication/sc_signal_rv/test03/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal_rv/test03/expected_returncode
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/src/systemc/tests/systemc/communication/sc_signal_rv/test03/expected_returncode
@@ -0,0 +1 @@
+1