systemc: Ensure resets and edges are notified when signaling a change.

Boolean sc_buffers (either pure bool or sc_dt::sc_logic) should signal
positive and negative edges and resets even when their value doesn't
change, unlike sc_signals. The spec doesn't actually say that and just
mentions the value changed event, but it may have been implied that the
other types of events also happen, they just made special mention of
the value change event.

This change moves some code around a bit so that when _signalChange()
is called, if the underlying type is a boolean signal, it will
automatically notify the appropriate edge event and signal any reset.
Putting the functionality in _signalChange instead of delegating it to
the sc_buffer lets us have a single template for sc_buffer and makes
the base class template specialization handle whether the edge events
exist, and if so which should be notified.

Change-Id: Ic4ca86afc3fde6a9df5c15a0a7386e24ac89a9e2
Reviewed-on: https://gem5-review.googlesource.com/c/14916
Reviewed-by: Matthias Jung <jungma@eit.uni-kl.de>
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-12-04 16:17:30 -08:00
parent 7fa4c94638
commit c04578791e
2 changed files with 39 additions and 15 deletions

View File

@@ -69,6 +69,20 @@ ScSignalBase::_signalChange()
_valueChangedEvent.notify(sc_core::SC_ZERO_TIME);
}
void
ScSignalBaseBinary::_signalPosedge()
{
_posStamp = getChangeStamp();
_posedgeEvent.notify(sc_core::SC_ZERO_TIME);
}
void
ScSignalBaseBinary::_signalNegedge()
{
_negStamp = getChangeStamp();
_negedgeEvent.notify(sc_core::SC_ZERO_TIME);
}
namespace
{

View File

@@ -96,6 +96,9 @@ class ScSignalBaseBinary : public ScSignalBase
uint64_t _posStamp;
uint64_t _negStamp;
void _signalPosedge();
void _signalNegedge();
};
template <class T>
@@ -357,15 +360,18 @@ class sc_signal<bool, WRITER_POLICY> :
return;
this->m_cur_val = this->m_new_val;
this->_signalReset();
this->_signalChange();
if (this->m_cur_val) {
this->_posStamp = ::sc_gem5::getChangeStamp();
this->_posedgeEvent.notify(SC_ZERO_TIME);
} else {
this->_negStamp = ::sc_gem5::getChangeStamp();
this->_negedgeEvent.notify(SC_ZERO_TIME);
}
}
void
_signalChange()
{
sc_gem5::ScSignalBinary<bool, WRITER_POLICY>::_signalChange();
this->_signalReset();
if (this->m_cur_val)
this->_signalPosedge();
else
this->_signalNegedge();
}
private:
@@ -421,13 +427,17 @@ class sc_signal<sc_dt::sc_logic, WRITER_POLICY> :
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()
{
sc_gem5::ScSignalBinary<sc_dt::sc_logic, WRITER_POLICY>::
_signalChange();
if (this->m_cur_val == sc_dt::SC_LOGIC_1)
this->_signalPosedge();
else if (this->m_cur_val == sc_dt::SC_LOGIC_0)
this->_signalNegedge();
}
private: