diff options
Diffstat (limited to 'ext/systemc/src/sysc/communication/sc_signal.cpp')
-rw-r--r-- | ext/systemc/src/sysc/communication/sc_signal.cpp | 456 |
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! |