From: Gabe Black Date: Sat, 15 Sep 2018 22:24:28 +0000 (-0700) Subject: systemc: Implement the sc_signal_rv channel and ports. X-Git-Tag: v19.0.0.0~1605 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dd017903991f51e1fa8df8dbc21cbb4a1501c1c1;p=gem5.git 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 Maintainer: Gabe Black --- 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 + #include "sc_in.hh" +#include "sc_signal_rv.hh" namespace sc_dt { @@ -51,7 +54,18 @@ class sc_in_rv : public sc_in> explicit sc_in_rv(const char *name) : sc_in>(name) {} virtual ~sc_in_rv() {}; - virtual void end_of_elaboration() {} + virtual void + end_of_elaboration() + { + sc_in >::end_of_elaboration(); + if (!dynamic_cast *>(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 + #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> virtual ~sc_inout_rv() {} sc_inout_rv & - operator = (const sc_dt::sc_lv &) + operator = (const sc_dt::sc_lv &l) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(l); return *this; } sc_inout_rv & - operator = (const sc_signal_in_if> &) + operator = (const sc_signal_in_if> &i) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(i.read()); return *this; } sc_inout_rv & - operator = (const sc_port>, 1> &) + operator = (const sc_port>, 1> &p) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(p->read()); return *this; } sc_inout_rv & - operator = (const sc_port>, 1> &) + operator = (const sc_port>, 1> &p) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(p->read()); return *this; } sc_inout_rv & - operator = (const sc_inout_rv &) + operator = (const sc_inout_rv &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 >::end_of_elaboration(); + if (!dynamic_cast *>(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 virtual ~sc_out_rv() {}; sc_out_rv & - operator = (const sc_dt::sc_lv &) + operator = (const sc_dt::sc_lv &l) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(l); return *this; } sc_out_rv & - operator = (const sc_signal_in_if> &) + operator = (const sc_signal_in_if> &i) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(i.read()); return *this; } sc_out_rv & - operator = (const sc_port>, 1> &) + operator = (const sc_port>, 1> &p) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(p->read()); return *this; } sc_out_rv & - operator = (const sc_port>, 1> &) + operator = (const sc_port>, 1> &p) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + (*this)->write(p->read()); return *this; } sc_out_rv & - operator = (const sc_out_rv &) + operator = (const sc_out_rv &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_MANY_WRITERS> } virtual void - write(const sc_dt::sc_lv &) + write(const sc_dt::sc_lv &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 & - operator = (const sc_dt::sc_lv &) + operator = (const sc_dt::sc_lv &l) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + write(l); return *this; } sc_signal_rv & - operator = (const sc_signal_rv &) + operator = (const sc_signal_rv &r) { - sc_channel_warn_unimpl(__PRETTY_FUNCTION__); + write(r.read()); return *this; } @@ -89,7 +101,28 @@ class sc_signal_rv : public sc_signal, 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_MANY_WRITERS>::update(); } private: @@ -97,6 +130,8 @@ class sc_signal_rv : public sc_signal, SC_MANY_WRITERS> sc_signal_rv(const sc_signal_rv &) : sc_signal, SC_MANY_WRITERS>() {} + + std::map<::sc_gem5::Process *, sc_dt::sc_lv > 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