summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/communication/sc_signal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/communication/sc_signal.cpp')
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal.cpp456
1 files changed, 456 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/communication/sc_signal.cpp b/ext/systemc/src/sysc/communication/sc_signal.cpp
new file mode 100644
index 000000000..3b2df8a7c
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal.cpp
@@ -0,0 +1,456 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal.cpp -- The sc_signal<T> primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/kernel/sc_reset.h"
+
+#include <sstream>
+
+using sc_dt::sc_lv_base;
+using sc_dt::sc_signed;
+using sc_dt::sc_unsigned;
+using sc_dt::int64;
+using sc_dt::uint64;
+
+namespace sc_core {
+
+// to avoid code bloat in sc_signal<T>
+
+void
+sc_signal_invalid_writer( sc_object* target, sc_object* first_writer,
+ sc_object* second_writer, bool check_delta )
+{
+ if ( second_writer )
+ {
+ std::stringstream msg;
+
+ msg
+ << "\n signal "
+ "`" << target->name() << "' "
+ "(" << target->kind() << ")"
+ << "\n first driver "
+ "`" << first_writer->name() << "' "
+ " (" << first_writer->kind() << ")"
+ << "\n second driver "
+ "`" << second_writer->name() << "' "
+ "(" << second_writer->kind() << ")";
+
+ if( check_delta )
+ {
+ msg << "\n first conflicting write in delta cycle "
+ << sc_delta_count();
+ }
+ SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_,
+ msg.str().c_str() );
+ }
+}
+
+bool
+sc_writer_policy_check_port::
+ check_port( sc_object* target, sc_port_base * port_, bool is_output )
+{
+ if ( is_output && sc_get_curr_simcontext()->write_check() )
+ {
+ // an out or inout port; only one can be connected
+ if( m_output != 0) {
+ sc_signal_invalid_writer( target, m_output, port_, false );
+ return false;
+ } else {
+ m_output = port_;
+ }
+ }
+ return true;
+}
+
+void sc_deprecated_get_data_ref()
+{
+ static bool warn_get_data_ref_deprecated=true;
+ if ( warn_get_data_ref_deprecated )
+ {
+ warn_get_data_ref_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "get_data_ref() is deprecated, use read() instead" );
+ }
+}
+
+void sc_deprecated_get_new_value()
+{
+ static bool warn_new_value=true;
+ if ( warn_new_value )
+ {
+ warn_new_value=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_signal<T>::get_new_value() is deprecated");
+ }
+}
+
+void sc_deprecated_trace()
+{
+ static bool warn_trace_deprecated=true;
+ if ( warn_trace_deprecated )
+ {
+ warn_trace_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_signal<T>::trace() is deprecated");
+ }
+}
+
+sc_event*
+sc_lazy_kernel_event( sc_event** ev, const char* name )
+{
+ if ( !*ev ) {
+ std::string kernel_name = SC_KERNEL_EVENT_PREFIX "_";
+ kernel_name.append( name );
+ *ev = new sc_event( kernel_name.c_str() );
+ }
+ return *ev;
+
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::register_port( sc_port_base& port_,
+ const char* if_typename_ )
+{
+ bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
+ if( !policy_type::check_port( this, &port_, is_output ) )
+ ((void)0); // fallback? error has been suppressed ...
+}
+
+
+// write the new value
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::write( const bool& value_ )
+{
+ bool value_changed = !( m_cur_val == value_ );
+ if ( !policy_type::check_write(this, value_changed) )
+ return;
+ m_new_val = value_;
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<bool,POL>::print( ::std::ostream& os ) const
+{
+ os << m_cur_val;
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::dump( ::std::ostream& os ) const
+{
+ os << " name = " << name() << ::std::endl;
+ os << " value = " << m_cur_val << ::std::endl;
+ os << "new value = " << m_new_val << ::std::endl;
+}
+
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::update()
+{
+ policy_type::update();
+ if( !( m_new_val == m_cur_val ) ) {
+ do_update();
+ }
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::do_update()
+{
+ // order of execution below is important, the notify_processes() call
+ // must come after the update of m_cur_val for things to work properly!
+
+ m_cur_val = m_new_val;
+
+ if ( m_reset_p ) m_reset_p->notify_processes();
+
+ if ( m_change_event_p ) m_change_event_p->notify_next_delta();
+
+ sc_event* event_p = this->m_cur_val
+ ? m_posedge_event_p : m_negedge_event_p;
+ if ( event_p ) event_p->notify_next_delta();
+
+ m_change_stamp = simcontext()->change_stamp();
+}
+
+// (edge) event methods
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::value_changed_event() const
+{
+ return *sc_lazy_kernel_event(&m_change_event_p,"value_changed_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::posedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_posedge_event_p,"posedge_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::negedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_negedge_event_p,"negedge_event");
+}
+
+
+// reset support:
+
+template< sc_writer_policy POL >
+sc_reset*
+sc_signal<bool,POL>::is_reset() const
+{
+ sc_reset* result_p;
+ if ( !m_reset_p ) m_reset_p = new sc_reset( this );
+ result_p = m_reset_p;
+ return result_p;
+}
+
+// destructor
+
+template< sc_writer_policy POL >
+sc_signal<bool,POL>::~sc_signal()
+{
+ delete m_change_event_p;
+ delete m_negedge_event_p;
+ delete m_posedge_event_p;
+ delete m_reset_p;
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::register_port( sc_port_base& port_,
+ const char* if_typename_ )
+{
+ bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
+ if( !policy_type::check_port( this, &port_, is_output ) )
+ ((void)0); // fallback? error has been suppressed ...
+}
+
+
+// write the new value
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<sc_dt::sc_logic,POL>::write( const sc_dt::sc_logic& value_ )
+{
+ bool value_changed = !( m_cur_val == value_ );
+ if ( !policy_type::check_write(this, value_changed) )
+ return;
+
+ m_new_val = value_;
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<sc_dt::sc_logic,POL>::print( ::std::ostream& os ) const
+{
+ os << m_cur_val;
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::dump( ::std::ostream& os ) const
+{
+ os << " name = " << name() << ::std::endl;
+ os << " value = " << m_cur_val << ::std::endl;
+ os << "new value = " << m_new_val << ::std::endl;
+}
+
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::update()
+{
+ policy_type::update();
+ if( !( m_new_val == m_cur_val ) ) {
+ do_update();
+ }
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::do_update()
+{
+ m_cur_val = m_new_val;
+
+ if ( m_change_event_p ) m_change_event_p->notify_next_delta();
+
+ if( m_posedge_event_p && (this->m_cur_val == sc_dt::SC_LOGIC_1) ) {
+ m_posedge_event_p->notify_next_delta();
+ }
+ else if( m_negedge_event_p && (this->m_cur_val == sc_dt::SC_LOGIC_0) ) {
+ m_negedge_event_p->notify_next_delta();
+ }
+
+ m_change_stamp = simcontext()->change_stamp();
+}
+
+// (edge) event methods
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::value_changed_event() const
+{
+ return *sc_lazy_kernel_event(&m_change_event_p,"value_changed_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::posedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_posedge_event_p,"posedge_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::negedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_negedge_event_p,"negedge_event");
+}
+
+
+// template instantiations for writer policies
+
+template class sc_signal<bool,SC_ONE_WRITER>;
+template class sc_signal<bool,SC_MANY_WRITERS>;
+template class sc_signal<bool,SC_UNCHECKED_WRITERS>;
+
+template class sc_signal<sc_dt::sc_logic,SC_ONE_WRITER>;
+template class sc_signal<sc_dt::sc_logic,SC_MANY_WRITERS>;
+template class sc_signal<sc_dt::sc_logic,SC_UNCHECKED_WRITERS>;
+
+} // namespace sc_core
+
+/*
+$Log: sc_signal.cpp,v $
+Revision 1.9 2011/08/26 20:45:42 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.8 2011/02/18 20:23:45 acg
+ Andy Goodrich: Copyright update.
+
+Revision 1.7 2011/02/18 20:08:14 acg
+ Philipp A. Hartmann: addition of include for sstream for MSVC.
+
+Revision 1.6 2011/01/25 20:50:37 acg
+ Andy Goodrich: changes for IEEE 1666 2011.
+
+Revision 1.5 2010/12/07 19:50:36 acg
+ Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+
+Revision 1.3 2007/04/09 21:59:49 acg
+ Andy Goodrich: fixed multiple write notification bug where writes
+ done outside the simulator were being treated as multiple writes.
+
+Revision 1.2 2007/04/02 17:24:01 acg
+ Andy Goodrich: added check for null writer pointers in sc_signal invalid
+ writer method.
+
+Revision 1.1.1.1 2006/12/15 20:20:04 acg
+SystemC 2.3
+
+Revision 1.7 2006/04/11 23:11:57 acg
+ Andy Goodrich: Changes for reset support that only includes
+ sc_cthread_process instances.
+
+Revision 1.6 2006/03/13 20:19:44 acg
+ Andy Goodrich: changed sc_event instances into pointers to sc_event instances
+ that are allocated as needed. This saves considerable storage for large
+ numbers of signals, etc.
+
+Revision 1.5 2006/01/25 00:31:11 acg
+ Andy Goodrich: Changed over to use a standard message id of
+ SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+
+Revision 1.4 2006/01/24 20:46:32 acg
+Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+using notify(SC_ZERO_TIME) in place of notify_delayed().
+
+Revision 1.3 2006/01/18 21:42:26 acg
+Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+port usage.
+
+Revision 1.2 2006/01/03 23:18:26 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:43 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.14 2005/09/15 23:01:51 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.13 2005/05/08 19:04:06 acg
+Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.
+
+Revision 1.12 2005/04/04 00:15:51 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.10 2005/03/21 22:31:32 acg
+Changes to sc_core namespace.
+
+Revision 1.9 2004/09/27 21:02:54 acg
+Andy Goodrich - Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments will appear in
+ checked out source.
+
+*/
+
+// Taf!