systemc: Ensure resets and edges are notified when signaling a change.
authorGabe Black <gabeblack@google.com>
Wed, 5 Dec 2018 00:17:30 +0000 (16:17 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 18 Dec 2018 11:48:30 +0000 (11:48 +0000)
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>

src/systemc/channel/sc_signal.cc
src/systemc/ext/channel/sc_signal.hh

index e3a3cf575beb402ed08aefd7fac6b456aef6521a..4829dad307ba6f123ab0fbabb1d39211135014c3 100644 (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
 {
 
index 522638dde5d7a39ed6c24815b07b40962cb6ede0..a2cb55397ade930680f3b6146e4a54dc26d95824 100644 (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: