diff options
author | Gabe Black <gabeblack@google.com> | 2018-09-15 15:24:28 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-10-09 21:52:42 +0000 |
commit | dd017903991f51e1fa8df8dbc21cbb4a1501c1c1 (patch) | |
tree | 39f7e475414aaeef75dbb2bb2d9f7f7b30ff367f /src/systemc/ext/channel/sc_signal_rv.hh | |
parent | fad9488643dbf09e4d99b89b6b775fd6f1b24ba6 (diff) | |
download | gem5-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>
Diffstat (limited to 'src/systemc/ext/channel/sc_signal_rv.hh')
-rw-r--r-- | src/systemc/ext/channel/sc_signal_rv.hh | 49 |
1 files changed, 42 insertions, 7 deletions
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 |