diff options
author | Gabe Black <gabeblack@google.com> | 2018-10-01 22:02:21 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-10-16 00:46:10 +0000 |
commit | 167e6c06b5d61d54e3eab48d03eb50ec316aeec3 (patch) | |
tree | 55c43062a20d7d7fd5a1dff206c856c6521617cf | |
parent | c736ef1b2f6447be1dcd9c9e62cc072befa91443 (diff) | |
download | gem5-167e6c06b5d61d54e3eab48d03eb50ec316aeec3.tar.xz |
systemc: Implement writer policies.
This includes the nonstandard SC_NO_WRITE_CHECK #define which the
Accellera tests use and depend on.
Change-Id: I106c4c16160325725a00d5c337047251817dca32
Reviewed-on: https://gem5-review.googlesource.com/c/13203
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
12 files changed, 436 insertions, 357 deletions
diff --git a/src/systemc/channel/SConscript b/src/systemc/channel/SConscript index c83c233c9..fe7973770 100644 --- a/src/systemc/channel/SConscript +++ b/src/systemc/channel/SConscript @@ -35,4 +35,5 @@ if env['USE_SYSTEMC']: Source('sc_out_resolved.cc') Source('sc_mutex.cc') Source('sc_semaphore.cc') + Source('sc_signal.cc') Source('sc_signal_resolved.cc') diff --git a/src/systemc/channel/sc_signal.cc b/src/systemc/channel/sc_signal.cc new file mode 100644 index 000000000..e2c9bdf9e --- /dev/null +++ b/src/systemc/channel/sc_signal.cc @@ -0,0 +1,175 @@ +/* + * Copyright 2018 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include <sstream> + +#include "systemc/core/scheduler.hh" +#include "systemc/ext/channel/sc_signal.hh" +#include "systemc/ext/core/sc_main.hh" + +namespace sc_gem5 +{ + +ScSignalBase::ScSignalBase(const char *name) : + sc_core::sc_prim_channel(name), _changeStamp(~0ULL), + _gem5WriterPort(nullptr) +{} + +ScSignalBase::~ScSignalBase() {} + +const sc_core::sc_event & +ScSignalBase::defaultEvent() const +{ + return valueChangedEvent(); +} + +const sc_core::sc_event & +ScSignalBase::valueChangedEvent() const +{ + return _valueChangedEvent; +} + +bool +ScSignalBase::event() const +{ + return _changeStamp == getChangeStamp(); +} + +void +ScSignalBase::_signalChange() +{ + _changeStamp = getChangeStamp(); + _valueChangedEvent.notify(sc_core::SC_ZERO_TIME); +} + +namespace +{ + +void +reportSignalError(ScSignalBase *sig, sc_core::sc_object *first, + sc_core::sc_object *second, bool delta_conflict=false) +{ + std::ostringstream ss; + ss << "\n signal " << "`" << sig->name() << "' (" << sig->kind() << ")"; + ss << "\n first driver `" << first->name() << "' (" << + first->kind() << ")"; + ss << "\n second driver `" << second->name() << "' (" << + second->kind() << ")"; + if (delta_conflict) { + ss << "\n conflicting write in delta cycle " << + sc_core::sc_delta_count(); + } + SC_REPORT_ERROR( + "(E115) sc_signal<T> cannot have more than one driver", + ss.str().c_str()); +} + +} // anonymous namespace + +WriteChecker<sc_core::SC_ONE_WRITER>::WriteChecker(ScSignalBase *_sig) : + sig(_sig), firstPort(nullptr), proc(nullptr), writeStamp(~0ULL) +{} + +void +WriteChecker<sc_core::SC_ONE_WRITER>::checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name) +{ + if (iface_type_name == out_name) { + if (firstPort) + reportSignalError(sig, firstPort, &port); + firstPort = &port; + } +} + +void +WriteChecker<sc_core::SC_ONE_WRITER>::checkWriter() +{ + Process *p = scheduler.current(); + if (!p) + return; + uint64_t stamp = getChangeStamp(); + if (proc && proc != p) + reportSignalError(sig, proc, p); + proc = p; + writeStamp = stamp; +} + +WriteChecker<sc_core::SC_MANY_WRITERS>::WriteChecker(ScSignalBase *_sig) : + sig(_sig), proc(nullptr), writeStamp(~0ULL) +{} + +void +WriteChecker<sc_core::SC_MANY_WRITERS>::checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name) +{ + return; +} + +void +WriteChecker<sc_core::SC_MANY_WRITERS>::checkWriter() +{ + Process *p = scheduler.current(); + if (!p) + return; + uint64_t stamp = getChangeStamp(); + if (writeStamp == stamp && proc && proc != p) + reportSignalError(sig, proc, p, writeStamp == stamp); + proc = p; + writeStamp = stamp; +} + +ScSignalBaseBinary::ScSignalBaseBinary(const char *_name) : + ScSignalBase(_name), _posStamp(~0ULL), _negStamp(~0ULL) +{} + +const sc_core::sc_event & +ScSignalBaseBinary::posedgeEvent() const +{ + return _posedgeEvent; +} + +const sc_core::sc_event & +ScSignalBaseBinary::negedgeEvent() const +{ + return _negedgeEvent; +} + +bool +ScSignalBaseBinary::posedge() const +{ + return _posStamp == getChangeStamp(); +} +bool + +ScSignalBaseBinary::negedge() const +{ + return _negStamp == getChangeStamp(); +} + +} // namespace sc_gem5 diff --git a/src/systemc/ext/channel/sc_buffer.hh b/src/systemc/ext/channel/sc_buffer.hh index 21dc52be0..c0ad710dd 100644 --- a/src/systemc/ext/channel/sc_buffer.hh +++ b/src/systemc/ext/channel/sc_buffer.hh @@ -50,6 +50,11 @@ class sc_buffer : public sc_signal<T, WRITER_POLICY> virtual void write(const T &t) { +# if !defined(SC_NO_WRITE_CHECK) + { + this->_checker.checkWriter(); + } +# endif this->m_new_val = t; this->request_update(); } diff --git a/src/systemc/ext/channel/sc_signal.hh b/src/systemc/ext/channel/sc_signal.hh index 672eef596..e4300343d 100644 --- a/src/systemc/ext/channel/sc_signal.hh +++ b/src/systemc/ext/channel/sc_signal.hh @@ -31,7 +31,6 @@ #define __SYSTEMC_EXT_CHANNEL_SC_SIGNAL_HH__ #include <iostream> -#include <sstream> #include <string> #include <vector> @@ -46,141 +45,265 @@ namespace sc_core class sc_port_base; -template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER> -class sc_signal : public sc_signal_inout_if<T>, - public sc_prim_channel +} // namespace sc_core + +namespace sc_gem5 +{ + +class Process; + +class ScSignalBase : public sc_core::sc_prim_channel { public: - sc_signal() : sc_signal_inout_if<T>(), - sc_prim_channel(sc_gen_unique_name("signal")), - m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL), - _gem5Writer(NULL) - {} - explicit sc_signal(const char *name) : - sc_signal_inout_if<T>(), sc_prim_channel(name), - m_cur_val(T()), m_new_val(T()), _changeStamp(~0ULL), - _gem5Writer(NULL) + virtual const char *kind() const { return "sc_signal"; } + + protected: + ScSignalBase(const char *_name); + virtual ~ScSignalBase(); + + const sc_core::sc_event &defaultEvent() const; + const sc_core::sc_event &valueChangedEvent() const; + + bool event() const; + + void _signalChange(); + + virtual sc_core::sc_writer_policy get_writer_policy() const = 0; + + sc_core::sc_event _valueChangedEvent; + uint64_t _changeStamp; + sc_core::sc_port_base *_gem5WriterPort; +}; + +class ScSignalBaseBinary : public ScSignalBase +{ + protected: + ScSignalBaseBinary(const char *_name); + + const sc_core::sc_event &posedgeEvent() const; + const sc_core::sc_event &negedgeEvent() const; + + bool posedge() const; + bool negedge() const; + + sc_core::sc_event _posedgeEvent; + sc_core::sc_event _negedgeEvent; + + uint64_t _posStamp; + uint64_t _negStamp; +}; + +template <class T> +class ScSignalBasePicker : public ScSignalBase +{ + protected: + ScSignalBasePicker(const char *_name) : ScSignalBase(_name) {} +}; + +template <> +class ScSignalBasePicker<bool> : public ScSignalBaseBinary +{ + protected: + ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {} +}; + +template <> +class ScSignalBasePicker<sc_dt::sc_logic> : public ScSignalBaseBinary +{ + protected: + ScSignalBasePicker(const char *_name) : ScSignalBaseBinary(_name) {} +}; + +template <sc_core::sc_writer_policy WRITER_POLICY> +class WriteChecker; + +template <> +class WriteChecker<sc_core::SC_ONE_WRITER> +{ + public: + WriteChecker(ScSignalBase *_sig); + + void checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name); + void checkWriter(); + + private: + ScSignalBase *sig; + sc_core::sc_port_base *firstPort; + Process *proc; + uint64_t writeStamp; +}; + +template <> +class WriteChecker<sc_core::SC_MANY_WRITERS> +{ + public: + WriteChecker(ScSignalBase *_sig); + + void checkPort(sc_core::sc_port_base &port, + std::string iface_type_name, std::string out_name); + void checkWriter(); + + private: + ScSignalBase *sig; + Process *proc; + uint64_t writeStamp; +}; + +template <class T, sc_core::sc_writer_policy WRITER_POLICY> +class ScSignalBaseT : + public ScSignalBasePicker<T>, public sc_core::sc_signal_inout_if<T> +{ + public: + ScSignalBaseT(const char *_name) : + ScSignalBasePicker<T>(_name), m_cur_val(T()), m_new_val(T()), + _checker(this) {} - explicit sc_signal(const char *name, const T &initial_value) : - sc_signal_inout_if<T>(), sc_prim_channel(name), - m_cur_val(initial_value), m_new_val(initial_value), - _changeStamp(~0ULL), _gem5Writer(NULL) + ScSignalBaseT(const char *_name, const T &initial_value) : + ScSignalBasePicker<T>(_name), m_cur_val(initial_value), + m_new_val(initial_value), _checker(this) {} - virtual ~sc_signal() {} + virtual ~ScSignalBaseT() {} virtual void - register_port(sc_port_base &port, const char *iface_type_name) + register_port(sc_core::sc_port_base &port, const char *iface_type_name) { - if (WRITER_POLICY == SC_ONE_WRITER && - std::string(iface_type_name) == - typeid(sc_signal_inout_if<T>).name()) { - if (_gem5Writer) { - std::ostringstream ss; - ss << "\n signal " << "`" << name() << "' (" << - kind() << ")"; - ss << "\n first driver `" << _gem5Writer->name() << "' (" << - _gem5Writer->kind() << ")"; - ss << "\n second driver `" << port.name() << "' (" << - port.kind() << ")"; - SC_REPORT_ERROR( - "(E115) sc_signal<T> cannot have more than one driver", - ss.str().c_str()); - } - _gem5Writer = &port; +# if !defined(SC_NO_WRITE_CHECK) + { + _checker.checkPort(port, iface_type_name, + typeid(sc_core::sc_signal_inout_if<T>).name()); } +# endif } virtual const T &read() const { return m_cur_val; } operator const T&() const { return read(); } - virtual sc_writer_policy - get_writer_policy() const - { - return WRITER_POLICY; - } virtual void write(const T &t) { +# if !defined(SC_NO_WRITE_CHECK) + { + _checker.checkWriter(); + } +# endif m_new_val = t; bool changed = !(m_cur_val == m_new_val); - //TODO check whether this write follows the write policy. if (changed) - request_update(); - } - sc_signal<T, WRITER_POLICY> & - operator = (const T &t) - { - write(t); - return *this; - } - sc_signal<T, WRITER_POLICY> & - operator = (const sc_signal<T, WRITER_POLICY> &s) - { - write(s.read()); - return *this; + this->request_update(); } - virtual const sc_event & + virtual const sc_core::sc_event & default_event() const { - return value_changed_event(); + return ScSignalBase::defaultEvent(); } - virtual const sc_event & + + virtual const sc_core::sc_event & value_changed_event() const { - return _valueChangedEvent; - } - virtual bool - event() const - { - return _changeStamp == ::sc_gem5::getChangeStamp(); + return ScSignalBase::valueChangedEvent(); } virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } virtual void dump(std::ostream &os=std::cout) const { - os << " name = " << name() << ::std::endl; + os << " name = " << this->name() << ::std::endl; os << " value = " << m_cur_val << ::std::endl; os << "new value = " << m_new_val << ::std::endl; } - virtual const char *kind() const { return "sc_signal"; } - - protected: - virtual void - update() - { - if (m_new_val == m_cur_val) - return; - m_cur_val = m_new_val; - _signalChange(); - _changeStamp = ::sc_gem5::getChangeStamp(); - _valueChangedEvent.notify(SC_ZERO_TIME); - } + virtual bool event() const { return ScSignalBase::event(); } - void - _signalChange() + virtual sc_core::sc_writer_policy + get_writer_policy() const { - _changeStamp = ::sc_gem5::getChangeStamp(); - _valueChangedEvent.notify(SC_ZERO_TIME); + return WRITER_POLICY; } + protected: // These members which store the current and future value of the signal // are not specified in the standard but are referred to directly by one // of the tests. T m_cur_val; T m_new_val; - private: - sc_event _valueChangedEvent; - uint64_t _changeStamp; - sc_port_base *_gem5Writer; + WriteChecker<WRITER_POLICY> _checker; +}; - // Disabled - sc_signal(const sc_signal<T, WRITER_POLICY> &) : - sc_signal_inout_if<T>(), sc_prim_channel("") +template <typename T, sc_core::sc_writer_policy WRITER_POLICY> +class ScSignalBinary : public ScSignalBaseT<T, WRITER_POLICY> +{ + public: + ScSignalBinary(const char *_name) : ScSignalBaseT<T, WRITER_POLICY>(_name) + {} + ScSignalBinary(const char *_name, const T& initial_value) : + ScSignalBaseT<T, WRITER_POLICY>(_name, initial_value) {} + + const sc_core::sc_event & + posedge_event() const + { + return ScSignalBaseBinary::posedgeEvent(); + } + const sc_core::sc_event & + negedge_event() const + { + return ScSignalBaseBinary::negedgeEvent(); + } + + bool posedge() const { return ScSignalBaseBinary::posedge(); } + bool negedge() const { return ScSignalBaseBinary::negedge(); } +}; + +} // namespace sc_gem5 + +namespace sc_core +{ + +template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER> +class sc_signal : public sc_gem5::ScSignalBaseT<T, WRITER_POLICY> +{ + public: + sc_signal() : sc_gem5::ScSignalBaseT<T, WRITER_POLICY>( + sc_gen_unique_name("signal")) + {} + explicit sc_signal(const char *name) : + sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name) + {} + explicit sc_signal(const char *name, const T &initial_value) : + sc_gem5::ScSignalBaseT<T, WRITER_POLICY>(name, initial_value) + {} + virtual ~sc_signal() {} + + sc_signal<T, WRITER_POLICY> & + operator = (const T &t) + { + this->write(t); + return *this; + } + sc_signal<T, WRITER_POLICY> & + operator = (const sc_signal<T, WRITER_POLICY> &s) + { + this->write(s.read()); + return *this; + } + + protected: + virtual void + update() + { + if (this->m_new_val == this->m_cur_val) + return; + + this->m_cur_val = this->m_new_val; + this->_signalChange(); + } + + private: + // Disabled + sc_signal(const sc_signal<T, WRITER_POLICY> &); }; template <class T, sc_writer_policy WRITER_POLICY> @@ -193,343 +316,110 @@ operator << (std::ostream &os, const sc_signal<T, WRITER_POLICY> &s) template <sc_writer_policy WRITER_POLICY> class sc_signal<bool, WRITER_POLICY> : - public sc_signal_inout_if<bool>, public sc_prim_channel + public sc_gem5::ScSignalBinary<bool, WRITER_POLICY> { public: - sc_signal() : sc_signal_inout_if<bool>(), - sc_prim_channel(sc_gen_unique_name("signal")), - m_cur_val(bool()), m_new_val(bool()), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_signal() : + sc_gem5::ScSignalBinary<bool, WRITER_POLICY>( + sc_gen_unique_name("signal")) {} explicit sc_signal(const char *name) : - sc_signal_inout_if<bool>(), sc_prim_channel(name), - m_cur_val(bool()), m_new_val(bool()), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name) {} explicit sc_signal(const char *name, const bool &initial_value) : - sc_signal_inout_if<bool>(), sc_prim_channel(name), - m_cur_val(initial_value), m_new_val(initial_value), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_gem5::ScSignalBinary<bool, WRITER_POLICY>(name, initial_value) {} virtual ~sc_signal() {} - virtual void - register_port(sc_port_base &port, const char *iface_type_name) - { - if (WRITER_POLICY == SC_ONE_WRITER && - std::string(iface_type_name) == - typeid(sc_signal_inout_if<bool>).name()) { - if (_gem5Writer) { - std::ostringstream ss; - ss << "\n signal " << "`" << name() << "' (" << - kind() << ")"; - ss << "\n first driver `" << _gem5Writer->name() << "' (" << - _gem5Writer->kind() << ")"; - ss << "\n second driver `" << port.name() << "' (" << - port.kind() << ")"; - SC_REPORT_ERROR( - "(E115) sc_signal<T> cannot have more than one driver", - ss.str().c_str()); - } - _gem5Writer = &port; - } - } - - virtual const bool &read() const { return m_cur_val; } - operator const bool &() const { return read(); } - - virtual sc_writer_policy - get_writer_policy() const - { - return WRITER_POLICY; - } - virtual void - write(const bool &b) - { - m_new_val = b; - bool changed = !(m_cur_val == m_new_val); - //TODO check whether this write follows the write policy. - if (changed) - request_update(); - } sc_signal<bool, WRITER_POLICY> & operator = (const bool &b) { - write(b); + this->write(b); return *this; } sc_signal<bool, WRITER_POLICY> & operator = (const sc_signal<bool, WRITER_POLICY> &s) { - write(s.read()); + this->write(s.read()); return *this; } - virtual const sc_event & - default_event() const - { - return value_changed_event(); - } - - virtual const sc_event & - value_changed_event() const - { - return _valueChangedEvent; - } - virtual const sc_event & - posedge_event() const - { - return _posedgeEvent; - } - virtual const sc_event & - negedge_event() const - { - return _negedgeEvent; - } - - virtual bool - event() const - { - return _changeStamp == ::sc_gem5::getChangeStamp(); - } - virtual bool - posedge() const - { - return _posStamp == ::sc_gem5::getChangeStamp(); - } - virtual bool - negedge() const - { - return _negStamp == ::sc_gem5::getChangeStamp(); - } - - virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } - virtual void - dump(std::ostream &os=std::cout) const - { - os << " name = " << name() << ::std::endl; - os << " value = " << m_cur_val << ::std::endl; - os << "new value = " << m_new_val << ::std::endl; - } - virtual const char *kind() const { return "sc_signal"; } - protected: virtual void update() { - if (m_new_val == m_cur_val) + if (this->m_new_val == this->m_cur_val) return; - m_cur_val = m_new_val; - _signalChange(); - if (m_cur_val) { - _posStamp = ::sc_gem5::getChangeStamp(); - _posedgeEvent.notify(SC_ZERO_TIME); + this->m_cur_val = this->m_new_val; + this->_signalChange(); + if (this->m_cur_val) { + this->_posStamp = ::sc_gem5::getChangeStamp(); + this->_posedgeEvent.notify(SC_ZERO_TIME); } else { - _negStamp = ::sc_gem5::getChangeStamp(); - _negedgeEvent.notify(SC_ZERO_TIME); + this->_negStamp = ::sc_gem5::getChangeStamp(); + this->_negedgeEvent.notify(SC_ZERO_TIME); } } - void - _signalChange() - { - _changeStamp = ::sc_gem5::getChangeStamp(); - _valueChangedEvent.notify(SC_ZERO_TIME); - } - - bool m_cur_val; - bool m_new_val; - private: - sc_event _valueChangedEvent; - sc_event _posedgeEvent; - sc_event _negedgeEvent; - - uint64_t _changeStamp; - uint64_t _posStamp; - uint64_t _negStamp; - - sc_port_base *_gem5Writer; - // Disabled - sc_signal(const sc_signal<bool, WRITER_POLICY> &) : - sc_signal_inout_if<bool>(), sc_prim_channel("") - {} + sc_signal(const sc_signal<bool, WRITER_POLICY> &); }; template <sc_writer_policy WRITER_POLICY> class sc_signal<sc_dt::sc_logic, WRITER_POLICY> : - public sc_signal_inout_if<sc_dt::sc_logic>, public sc_prim_channel + public sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY> { public: - sc_signal() : sc_signal_inout_if<sc_dt::sc_logic>(), - sc_prim_channel(sc_gen_unique_name("signal")), - m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_signal() : + sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>( + sc_gen_unique_name("signal")) {} explicit sc_signal(const char *name) : - sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name), - m_cur_val(sc_dt::sc_logic()), m_new_val(sc_dt::sc_logic()), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>(name) {} explicit sc_signal(const char *name, const sc_dt::sc_logic &initial_value) : - sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel(name), - m_cur_val(initial_value), m_new_val(initial_value), - _changeStamp(~0ULL), _posStamp(~0ULL), _negStamp(~0ULL), - _gem5Writer(NULL) + sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>( + name, initial_value) {} virtual ~sc_signal() {} - virtual void - register_port(sc_port_base &port, const char *iface_type_name) - { - if (WRITER_POLICY == SC_ONE_WRITER && - std::string(iface_type_name) == - typeid(sc_signal_inout_if<sc_dt::sc_logic>).name()) { - if (_gem5Writer) { - std::ostringstream ss; - ss << "\n signal " << "`" << name() << "' (" << - kind() << ")"; - ss << "\n first driver `" << _gem5Writer->name() << "' (" << - _gem5Writer->kind() << ")"; - ss << "\n second driver `" << port.name() << "' (" << - port.kind() << ")"; - SC_REPORT_ERROR( - "(E115) sc_signal<T> cannot have more than one driver", - ss.str().c_str()); - } - _gem5Writer = &port; - } - } - - virtual const sc_dt::sc_logic &read() const { return m_cur_val; } - operator const sc_dt::sc_logic &() const { return read(); } - - virtual sc_writer_policy - get_writer_policy() const - { - return WRITER_POLICY; - } - virtual void - write(const sc_dt::sc_logic &l) - { - m_new_val = l; - bool changed = !(m_cur_val == m_new_val); - //TODO check whether this write follows the write policy. - if (changed) - request_update(); - } sc_signal<sc_dt::sc_logic, WRITER_POLICY> & operator = (const sc_dt::sc_logic &l) { - write(l); + this->write(l); return *this; } sc_signal<sc_dt::sc_logic, WRITER_POLICY> & operator = (const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &s) { - write(s.read()); + this->write(s.read()); return *this; } - virtual const sc_event & - default_event() const - { - return value_changed_event(); - } - - virtual const sc_event & - value_changed_event() const - { - return _valueChangedEvent; - } - virtual const sc_event & - posedge_event() const - { - return _posedgeEvent; - } - virtual const sc_event & - negedge_event() const - { - return _negedgeEvent; - } - - virtual bool - event() const - { - return _changeStamp == ::sc_gem5::getChangeStamp(); - } - virtual bool - posedge() const - { - return _posStamp == ::sc_gem5::getChangeStamp(); - } - virtual bool - negedge() const - { - return _negStamp == ::sc_gem5::getChangeStamp(); - } - - virtual void print(std::ostream &os=std::cout) const { os << m_cur_val; } - virtual void - dump(std::ostream &os=std::cout) const - { - os << " name = " << name() << ::std::endl; - os << " value = " << m_cur_val << ::std::endl; - os << "new value = " << m_new_val << ::std::endl; - } - virtual const char *kind() const { return "sc_signal"; } - protected: virtual void update() { - if (m_new_val == m_cur_val) + if (this->m_new_val == this->m_cur_val) return; - m_cur_val = m_new_val; - _signalChange(); - if (m_cur_val == sc_dt::SC_LOGIC_1) { - _posStamp = ::sc_gem5::getChangeStamp(); - _posedgeEvent.notify(SC_ZERO_TIME); - } else if (m_cur_val == sc_dt::SC_LOGIC_0) { - _negStamp = ::sc_gem5::getChangeStamp(); - _negedgeEvent.notify(SC_ZERO_TIME); + this->m_cur_val = this->m_new_val; + this->_signalChange(); + if (this->m_cur_val == sc_dt::SC_LOGIC_1) { + this->_posStamp = ::sc_gem5::getChangeStamp(); + this->_posedgeEvent.notify(SC_ZERO_TIME); + } else if (this->m_cur_val == sc_dt::SC_LOGIC_0) { + this->_negStamp = ::sc_gem5::getChangeStamp(); + this->_negedgeEvent.notify(SC_ZERO_TIME); } } - void - _signalChange() - { - _changeStamp = ::sc_gem5::getChangeStamp(); - _valueChangedEvent.notify(SC_ZERO_TIME); - } - - sc_dt::sc_logic m_cur_val; - sc_dt::sc_logic m_new_val; - private: - sc_event _valueChangedEvent; - sc_event _posedgeEvent; - sc_event _negedgeEvent; - - uint64_t _changeStamp; - uint64_t _posStamp; - uint64_t _negStamp; - - sc_port_base *_gem5Writer; - // Disabled - sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &) : - sc_signal_inout_if<sc_dt::sc_logic>(), sc_prim_channel("") - {} + sc_signal(const sc_signal<sc_dt::sc_logic, WRITER_POLICY> &); }; } // namespace sc_core diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test01/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test01/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test01/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test02/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test02/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test02/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test03/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test03/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test03/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test04/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test04/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test04/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test05/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test05/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test05/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test07/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test07/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test07/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test14/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test14/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test14/expected_returncode @@ -0,0 +1 @@ +1 diff --git a/src/systemc/tests/systemc/communication/sc_signal/check_writer/test16/expected_returncode b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test16/expected_returncode new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/systemc/tests/systemc/communication/sc_signal/check_writer/test16/expected_returncode @@ -0,0 +1 @@ +1 |