| /***************************************************************************** |
| |
| 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_process.cpp -- Base process implementation. |
| |
| Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003 |
| Stuart Swan, Cadence |
| Bishnupriya Bhattacharya, Cadence Design Systems, |
| 25 August, 2003 |
| |
| CHANGE LOG AT THE END OF THE FILE |
| *****************************************************************************/ |
| |
| #include "sysc/kernel/sc_name_gen.h" |
| #include "sysc/kernel/sc_cthread_process.h" |
| #include "sysc/kernel/sc_method_process.h" |
| #include "sysc/kernel/sc_thread_process.h" |
| #include "sysc/kernel/sc_sensitive.h" |
| #include "sysc/kernel/sc_process_handle.h" |
| #include "sysc/kernel/sc_event.h" |
| #include <sstream> |
| |
| namespace sc_core { |
| |
| // sc_process_handle entities that are returned for null pointer instances: |
| // |
| // Note the special name for 'non_event' - this makes sure it does not |
| // appear as a named event. |
| |
| std::vector<sc_event*> sc_process_handle::empty_event_vector; |
| std::vector<sc_object*> sc_process_handle::empty_object_vector; |
| sc_event sc_process_handle::non_event(SC_KERNEL_EVENT_PREFIX); |
| |
| // Last process that was created: |
| |
| sc_process_b* sc_process_b::m_last_created_process_p = 0; |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::add_static_event" |
| // |
| // This method adds an event to the list of static events, and sets the |
| // event up to call back this process when it fires. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::add_static_event( const sc_event& e ) |
| { |
| sc_method_handle method_h; // This process as a method. |
| sc_thread_handle thread_h; // This process as a thread. |
| |
| |
| // CHECK TO SEE IF WE ARE ALREADY REGISTERED WITH THE EVENT: |
| |
| for( int i = m_static_events.size() - 1; i >= 0; -- i ) { |
| if( &e == m_static_events[i] ) { |
| return; |
| } |
| } |
| |
| // REMEMBER THE EVENT AND THEN REGISTER OUR OBJECT INSTANCE WITH IT: |
| |
| m_static_events.push_back( &e ); |
| |
| switch ( m_process_kind ) |
| { |
| case SC_THREAD_PROC_: |
| case SC_CTHREAD_PROC_: |
| thread_h = SCAST<sc_thread_handle>( this ); |
| e.add_static( thread_h ); |
| break; |
| case SC_METHOD_PROC_: |
| method_h = SCAST<sc_method_handle>( this ); |
| e.add_static( method_h ); |
| break; |
| default: |
| assert( false ); |
| break; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::disconnect_process" |
| // |
| // This method removes this object instance from use. It will be called by |
| // the kill_process() methods of classes derived from it. This object instance |
| // will be removed from any data structures it resides, other than existence. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::disconnect_process() |
| { |
| int mon_n; // monitor queue size. |
| sc_thread_handle thread_h; // This process as a thread. |
| |
| // IF THIS OBJECT IS PINING FOR THE FJORDS WE ARE DONE: |
| |
| if ( m_state & ps_bit_zombie ) return; |
| |
| // IF THIS IS A THREAD SIGNAL ANY MONITORS WAITING FOR IT TO EXIT: |
| |
| switch ( m_process_kind ) |
| { |
| case SC_THREAD_PROC_: |
| case SC_CTHREAD_PROC_: |
| thread_h = SCAST<sc_thread_handle>(this); |
| mon_n = thread_h->m_monitor_q.size(); |
| if ( mon_n ) |
| { |
| for ( int mon_i = 0; mon_i < mon_n; mon_i++ ) |
| { |
| thread_h->m_monitor_q[mon_i]->signal( thread_h, |
| sc_process_monitor::spm_exit); |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| |
| // REMOVE EVENT WAITS, AND REMOVE THE PROCESS FROM ITS SC_RESET: |
| |
| remove_dynamic_events(); |
| remove_static_events(); |
| |
| for ( std::vector<sc_reset*>::size_type rst_i = 0; rst_i < m_resets.size(); rst_i++ ) |
| { |
| m_resets[rst_i]->remove_process( this ); |
| } |
| m_resets.resize(0); |
| |
| |
| // FIRE THE TERMINATION EVENT, MARK AS TERMINATED, AND DECREMENT THE COUNT: |
| // |
| // (1) We wait to set the process kind until after doing the removals |
| // above. |
| // (2) Decrementing the reference count will result in actual object |
| // deletion if we hit zero. |
| |
| m_state = ps_bit_zombie; |
| if ( m_term_event_p ) m_term_event_p->notify(); |
| reference_decrement(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::delete_process" |
| // |
| // This method deletes the current instance, if it is not the running |
| // process. Otherwise, it is put in the simcontext's process deletion |
| // queue. |
| // |
| // The reason for the two step deletion process is that the process from which |
| // reference_decrement() is called may be the running process, so we may need |
| // to wait until it goes idle. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::delete_process() |
| { |
| assert( m_references_n == 0 ); |
| |
| // Immediate deletion: |
| |
| if ( this != sc_get_current_process_b() ) |
| { |
| delete this; |
| } |
| |
| // Deferred deletion: note we set the reference count to one for the call |
| // to reference_decrement that occurs in sc_simcontext::crunch(). |
| |
| else |
| { |
| m_references_n = 1; |
| detach(); |
| simcontext()->mark_to_collect_process( this ); |
| } |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::dont_initialize" |
| // |
| // This virtual method sets the initialization switch for this object instance. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::dont_initialize( bool dont ) |
| { |
| m_dont_init = dont; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::dump_state" |
| // |
| // This method returns the process state as a string. |
| //------------------------------------------------------------------------------ |
| std::string sc_process_b::dump_state() const |
| { |
| std::string result; |
| result = "["; |
| if ( m_state == ps_normal ) |
| { |
| result += " normal"; |
| } |
| else |
| { |
| if ( m_state & ps_bit_disabled ) |
| result += "disabled "; |
| if ( m_state & ps_bit_suspended ) |
| result += "suspended "; |
| if ( m_state & ps_bit_ready_to_run ) |
| result += "ready_to_run "; |
| if ( m_state & ps_bit_zombie ) |
| result += "zombie "; |
| } |
| result += "]"; |
| return result; |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::gen_unique_name" |
| // |
| // This method generates a unique name within this object instance's namespace. |
| //------------------------------------------------------------------------------ |
| const char* sc_process_b::gen_unique_name( const char* basename_, |
| bool preserve_first ) |
| { |
| if ( ! m_name_gen_p ) m_name_gen_p = new sc_name_gen; |
| return m_name_gen_p->gen_unique_name( basename_, preserve_first ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::remove_dynamic_events" |
| // |
| // This method removes this object instance from the events in its dynamic |
| // event lists. |
| // |
| // Arguments: |
| // skip_timeout = skip cleaning up the timeout event, it will be done |
| // by sc_event_notify(). |
| //------------------------------------------------------------------------------ |
| void |
| sc_process_b::remove_dynamic_events( bool skip_timeout ) |
| { |
| sc_method_handle method_h; // This process as a method. |
| sc_thread_handle thread_h; // This process as a thread. |
| |
| m_trigger_type = STATIC; |
| switch ( m_process_kind ) |
| { |
| case SC_THREAD_PROC_: |
| case SC_CTHREAD_PROC_: |
| thread_h = SCAST<sc_thread_handle>(this); |
| if ( thread_h->m_timeout_event_p && !skip_timeout ) { |
| thread_h->m_timeout_event_p->remove_dynamic(thread_h); |
| thread_h->m_timeout_event_p->cancel(); |
| } |
| if ( m_event_p ) m_event_p->remove_dynamic( thread_h ); |
| if ( m_event_list_p ) |
| { |
| m_event_list_p->remove_dynamic( thread_h, 0 ); |
| m_event_list_p->auto_delete(); |
| m_event_list_p = 0; |
| } |
| break; |
| case SC_METHOD_PROC_: |
| method_h = SCAST<sc_method_handle>(this); |
| if ( method_h->m_timeout_event_p && !skip_timeout ) { |
| method_h->m_timeout_event_p->remove_dynamic(method_h); |
| method_h->m_timeout_event_p->cancel(); |
| } |
| if ( m_event_p ) m_event_p->remove_dynamic( method_h ); |
| if ( m_event_list_p ) |
| { |
| m_event_list_p->remove_dynamic( method_h, 0 ); |
| m_event_list_p->auto_delete(); |
| m_event_list_p = 0; |
| } |
| break; |
| default: // Some other type, it needs to clean up itself. |
| // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl; |
| break; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::remove_static_events" |
| // |
| // This method removes this object instance from the events in its static |
| // event list. |
| //------------------------------------------------------------------------------ |
| void |
| sc_process_b::remove_static_events() |
| { |
| sc_method_handle method_h; // This process as a method. |
| sc_thread_handle thread_h; // This process as a thread. |
| |
| switch ( m_process_kind ) |
| { |
| case SC_THREAD_PROC_: |
| case SC_CTHREAD_PROC_: |
| thread_h = SCAST<sc_thread_handle>( this ); |
| for( int i = m_static_events.size() - 1; i >= 0; -- i ) { |
| m_static_events[i]->remove_static( thread_h ); |
| } |
| m_static_events.resize(0); |
| break; |
| case SC_METHOD_PROC_: |
| method_h = DCAST<sc_method_handle>( this ); |
| assert( method_h != 0 ); |
| for( int i = m_static_events.size() - 1; i >= 0; -- i ) { |
| m_static_events[i]->remove_static( method_h ); |
| } |
| m_static_events.resize(0); |
| break; |
| default: // Some other type, it needs to clean up itself. |
| // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl; |
| break; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| // "sc_process_b::report_error" |
| // |
| // This method can be used to issue a report from within a process. |
| // The error of the given ID is reported with the given message and |
| // the process' name() appended to the report. |
| //------------------------------------------------------------------------------ |
| void |
| sc_process_b::report_error( const char* msgid, const char* msg ) const |
| { |
| std::stringstream sstr; |
| if( msg && msg[0] ) |
| sstr << msg << ": "; |
| sstr << name(); |
| SC_REPORT_ERROR( msgid, sstr.str().c_str() ); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| // "sc_process_b::report_immediate_self_notification" |
| // |
| // This method is used to report an immediate self-notification |
| // that used to trigger the process before the clarification in 1666-2011. |
| // The warning is only reported once. |
| //------------------------------------------------------------------------------ |
| void |
| sc_process_b::report_immediate_self_notification() const |
| { |
| static bool once = false; |
| if( !once ) { |
| SC_REPORT_WARNING( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, name() ); |
| once = true; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::reset_changed" |
| // |
| // This method is called when there is a change in the value of the |
| // signal that was specified via reset_signal_is, or the value of the |
| // m_sticky_reset field. We get called any time m_sticky_reset changes |
| // or a signal value changes since, since we may need to throw an exception |
| // or clear one. Note that this method may be called when there is no |
| // active process, but rather the main simulator is executing so we must |
| // check for that case. |
| // |
| // Arguments: |
| // async = true if this is an asynchronous reset. |
| // asserted = true if reset being asserted, false if being deasserted. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::reset_changed( bool async, bool asserted ) |
| { |
| |
| // Error out on the corner case: |
| |
| if ( !sc_allow_process_control_corners && !async && |
| (m_state & ps_bit_suspended) ) |
| { |
| report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_, |
| "synchronous reset changed on a suspended process" ); |
| } |
| |
| // IF THIS OBJECT IS PUSHING UP DAISIES WE ARE DONE: |
| |
| if ( m_state & ps_bit_zombie ) return; |
| |
| // Reset is being asserted: |
| |
| if ( asserted ) |
| { |
| // if ( m_reset_event_p ) m_reset_event_p->notify(); |
| if ( async ) |
| { |
| m_active_areset_n++; |
| if ( sc_is_running() ) throw_reset(true); |
| } |
| else |
| { |
| m_active_reset_n++; |
| if ( sc_is_running() ) throw_reset(false); |
| } |
| } |
| |
| // Reset is being deasserted: |
| |
| else |
| { |
| if ( async ) |
| { |
| m_active_areset_n--; |
| } |
| else |
| { |
| m_active_reset_n--; |
| } |
| } |
| |
| // Clear the throw type if there are no active resets. |
| |
| if ( (m_throw_status == THROW_SYNC_RESET || |
| m_throw_status == THROW_ASYNC_RESET) && |
| m_active_areset_n == 0 && m_active_reset_n == 0 && !m_sticky_reset ) |
| { |
| m_throw_status = THROW_NONE; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::reset_event" |
| // |
| // This method returns a reference to the reset event for this object |
| // instance. If no event exists one is allocated. |
| //------------------------------------------------------------------------------ |
| sc_event& sc_process_b::reset_event() |
| { |
| if ( !m_reset_event_p ) |
| { |
| m_reset_event_p = new sc_event( |
| (std::string(SC_KERNEL_EVENT_PREFIX)+"_reset_event").c_str() ); |
| } |
| return *m_reset_event_p; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::reset_process" |
| // |
| // This inline method changes the reset state of this object instance and |
| // conditionally its descendants. |
| // |
| // Notes: |
| // (1) It is called for sync_reset_on() and sync_reset_off(). It is not used |
| // for signal sensitive resets, though all reset flow ends up in |
| // reset_changed(). |
| // |
| // Arguments: |
| // rt = source of the reset: |
| // * reset_asynchronous - sc_process_handle::reset() |
| // * reset_synchronous_off - sc_process_handle::sync_reset_off() |
| // * reset_synchronous_on - sc_process_handle::sync_reset_on() |
| // descendants = indication of how to process descendants. |
| //------------------------------------------------------------------------------ |
| void sc_process_b::reset_process( reset_type rt, |
| sc_descendant_inclusion_info descendants ) |
| { |
| |
| // PROCESS THIS OBJECT INSTANCE'S DESCENDANTS IF REQUESTED TO: |
| |
| if ( descendants == SC_INCLUDE_DESCENDANTS ) |
| { |
| const std::vector<sc_object*> children = get_child_objects(); |
| int child_n = children.size(); |
| |
| for ( int child_i = 0; child_i < child_n; child_i++ ) |
| { |
| sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); |
| if ( child_p ) child_p->reset_process(rt, descendants); |
| } |
| } |
| |
| // PROCESS THIS OBJECT INSTANCE: |
| |
| switch (rt) |
| { |
| // One-shot asynchronous reset: remove dynamic sensitivity and throw: |
| // |
| // If this is an sc_method only throw if it is active. |
| |
| case reset_asynchronous: |
| if ( sc_get_status() != SC_RUNNING ) |
| { |
| report_error(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_); |
| } |
| else |
| { |
| remove_dynamic_events(); |
| throw_reset(true); |
| } |
| break; |
| |
| // Turn on sticky synchronous reset: use standard reset mechanism. |
| |
| case reset_synchronous_on: |
| if ( m_sticky_reset == false ) |
| { |
| m_sticky_reset = true; |
| reset_changed( false, true ); |
| } |
| break; |
| |
| // Turn off sticky synchronous reset: use standard reset mechanism. |
| |
| default: |
| if ( m_sticky_reset == true ) |
| { |
| m_sticky_reset = false; |
| reset_changed( false, false ); |
| } |
| break; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::sc_process_b" |
| // |
| // This is the object instance constructor for this class. |
| //------------------------------------------------------------------------------ |
| sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host, |
| SC_ENTRY_FUNC method_p, sc_process_host* host_p, |
| const sc_spawn_options* /* opt_p */ |
| ) : |
| sc_object( name_p ), |
| file(0), |
| lineno(0), |
| proc_id( simcontext()->next_proc_id()), |
| m_active_areset_n(0), |
| m_active_reset_n(0), |
| m_dont_init( false ), |
| m_dynamic_proc( simcontext()->elaboration_done() ), |
| m_event_p(0), |
| m_event_count(0), |
| m_event_list_p(0), |
| m_exist_p(0), |
| m_free_host( free_host ), |
| m_has_reset_signal( false ), |
| m_has_stack(false), |
| m_is_thread(is_thread), |
| m_last_report_p(0), |
| m_name_gen_p(0), |
| m_process_kind(SC_NO_PROC_), |
| m_references_n(1), |
| m_resets(), |
| m_reset_event_p(0), |
| m_resume_event_p(0), |
| m_runnable_p(0), |
| m_semantics_host_p( host_p ), |
| m_semantics_method_p ( method_p ), |
| m_state(ps_normal), |
| m_static_events(), |
| m_sticky_reset(false), |
| m_term_event_p(0), |
| m_throw_helper_p(0), |
| m_throw_status( THROW_NONE ), |
| m_timed_out(false), |
| m_timeout_event_p(0), |
| m_trigger_type(STATIC), |
| m_unwinding(false) |
| { |
| |
| // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS: |
| |
| m_last_created_process_p = this; |
| m_timeout_event_p = new sc_event( |
| (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::~sc_process_b" |
| // |
| // This is the object instance destructor for this class. |
| //------------------------------------------------------------------------------ |
| sc_process_b::~sc_process_b() |
| { |
| |
| // REDIRECT ANY CHILDREN AS CHILDREN OF THE SIMULATION CONTEXT: |
| |
| orphan_child_objects(); |
| |
| |
| // DELETE SEMANTICS OBJECTS IF NEED BE: |
| |
| if ( m_free_host ) delete m_semantics_host_p; |
| # if !defined(SC_USE_MEMBER_FUNC_PTR) // Remove invocation object. |
| delete m_semantics_method_p; |
| # endif |
| |
| |
| // REMOVE ANY STRUCTURES THAT MAY HAVE BEEN BUILT: |
| |
| delete m_last_report_p; |
| delete m_name_gen_p; |
| delete m_reset_event_p; |
| delete m_resume_event_p; |
| delete m_term_event_p; |
| delete m_throw_helper_p; |
| delete m_timeout_event_p; |
| |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_b::terminated_event" |
| // |
| // This method returns a reference to the terminated event for this object |
| // instance. If no event exists one is allocated. |
| //------------------------------------------------------------------------------ |
| sc_event& sc_process_b::terminated_event() |
| { |
| if ( !m_term_event_p ) |
| { |
| m_term_event_p = new sc_event( |
| (std::string(SC_KERNEL_EVENT_PREFIX)+"_term_event").c_str() ); |
| } |
| return *m_term_event_p; |
| } |
| |
| // +---------------------------------------------------------------------------- |
| // |"sc_process_b::trigger_reset_event" |
| // | |
| // | This method triggers the notify event. It exists because we can't get |
| // | sc_event context in sc_process.h because the includes would be |
| // | circular... sigh... |
| // +---------------------------------------------------------------------------- |
| void sc_process_b::trigger_reset_event() |
| { |
| if ( m_reset_event_p ) m_reset_event_p->notify(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_handle::operator sc_cthread_handle" |
| // |
| //------------------------------------------------------------------------------ |
| sc_process_handle::operator sc_cthread_handle() |
| { |
| return DCAST<sc_cthread_handle>(m_target_p); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_handle::sc_method_handle" |
| // |
| //------------------------------------------------------------------------------ |
| sc_process_handle::operator sc_method_handle() |
| { |
| return DCAST<sc_method_handle>(m_target_p); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //"sc_process_handle::sc_thread_handle" |
| // |
| //------------------------------------------------------------------------------ |
| sc_process_handle::operator sc_thread_handle() |
| { |
| return DCAST<sc_thread_handle>(m_target_p); |
| } |
| |
| } // namespace sc_core |
| |
| |
| /***************************************************************************** |
| |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and |
| changes you are making here. |
| |
| Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05 |
| Description of Modification: This is the rewrite of process support. It |
| contains some code from the now-defunct |
| sc_process_b.cpp, as well as the former |
| version of sc_process_b.cpp. |
| |
| Name, Affiliation, Date: |
| Description of Modification: |
| |
| *****************************************************************************/ |
| |
| // $Log: sc_process.cpp,v $ |
| // Revision 1.37 2011/08/24 22:05:51 acg |
| // Torsten Maehne: initialization changes to remove warnings. |
| // |
| // Revision 1.36 2011/08/15 16:43:24 acg |
| // Torsten Maehne: changes to remove unused argument warnings. |
| // |
| // Revision 1.35 2011/08/07 19:08:04 acg |
| // Andy Goodrich: moved logs to end of file so line number synching works |
| // better between versions. |
| // |
| // Revision 1.34 2011/07/29 22:55:01 acg |
| // Philipp A. Hartmann: add missing include. |
| // |
| // Revision 1.33 2011/07/29 22:43:41 acg |
| // Philipp A. Hartmann: changes to handle case where a process control |
| // invocation on a child process causes the list of child processes to change. |
| // |
| // Revision 1.32 2011/07/24 11:20:03 acg |
| // Philipp A. Hartmann: process control error message improvements: |
| // (1) Downgrade error to warning for re-kills of processes. |
| // (2) Add process name to process messages. |
| // (3) drop some superfluous colons in messages. |
| // |
| // Revision 1.31 2011/04/19 15:04:27 acg |
| // Philipp A. Hartmann: clean up SC_ID messages. |
| // |
| // Revision 1.30 2011/04/14 22:33:43 acg |
| // Andy Goodrich: added missing checks for a process being a zombie. |
| // |
| // Revision 1.29 2011/04/13 05:00:43 acg |
| // Andy Goodrich: removed check for method process in termination_event() |
| // since with the new IEEE 1666 2011 its legal. |
| // |
| // Revision 1.28 2011/04/13 02:44:26 acg |
| // Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the |
| // throw status will be set back to THROW_*_RESET if reset is active and |
| // the check for an unwind being complete was expecting THROW_NONE as the |
| // clearing of THROW_NOW. |
| // |
| // Revision 1.27 2011/04/10 22:17:35 acg |
| // Andy Goodrich: added trigger_reset_event() to allow sc_process.h to |
| // contain the run_process() inline method. sc_process.h cannot have |
| // sc_simcontext information because of recursive includes. |
| // |
| // Revision 1.26 2011/04/08 22:33:08 acg |
| // Andy Goodrich: moved the semantics() method to the header file and made |
| // it an inline method. |
| // |
| // Revision 1.25 2011/04/08 18:24:48 acg |
| // Andy Goodrich: moved reset_changed() to .cpp since it needs visibility |
| // to sc_simcontext. |
| // |
| // Revision 1.24 2011/04/05 20:50:57 acg |
| // Andy Goodrich: |
| // (1) changes to make sure that event(), posedge() and negedge() only |
| // return true if the clock has not moved. |
| // (2) fixes for method self-resumes. |
| // (3) added SC_PRERELEASE_VERSION |
| // (4) removed kernel events from the object hierarchy, added |
| // sc_hierarchy_name_exists(). |
| // |
| // Revision 1.23 2011/04/05 06:25:38 acg |
| // Andy Goodrich: new checks for simulation running in reset_process(). |
| // |
| // Revision 1.22 2011/03/20 13:43:23 acg |
| // Andy Goodrich: added async_signal_is() plus suspend() as a corner case. |
| // |
| // Revision 1.21 2011/03/12 21:07:51 acg |
| // Andy Goodrich: changes to kernel generated event support. |
| // |
| // Revision 1.20 2011/03/07 17:38:43 acg |
| // Andy Goodrich: tightening up of checks for undefined interaction between |
| // synchronous reset and suspend. |
| // |
| // Revision 1.19 2011/03/06 23:30:13 acg |
| // Andy Goodrich: refining suspend - sync reset corner case checking so that |
| // the following are error situations: |
| // (1) Calling suspend on a process with a reset_signal_is() specification |
| // or sync_reset_on() is active. |
| // (2) Calling sync_reset_on() on a suspended process. |
| // |
| // Revision 1.18 2011/03/06 19:57:11 acg |
| // Andy Goodrich: refinements for the illegal suspend - synchronous reset |
| // interaction. |
| // |
| // Revision 1.17 2011/03/06 16:47:09 acg |
| // Andy Goodrich: changes for testing sync_reset - suspend corner cases. |
| // |
| // Revision 1.16 2011/03/06 15:57:57 acg |
| // Andy Goodrich: added process control corner case checks. Changes for |
| // named events. |
| // |
| // Revision 1.15 2011/02/18 20:27:14 acg |
| // Andy Goodrich: Updated Copyrights. |
| // |
| // Revision 1.14 2011/02/17 19:52:13 acg |
| // Andy Goodrich: |
| // (1) Simplfied process control usage. |
| // (2) Changed dump_status() to dump_state with new signature. |
| // |
| // Revision 1.13 2011/02/13 21:47:37 acg |
| // Andy Goodrich: update copyright notice. |
| // |
| // Revision 1.12 2011/02/13 21:41:34 acg |
| // Andy Goodrich: get the log messages for the previous check in correct. |
| // |
| // Revision 1.11 2011/02/13 21:32:24 acg |
| // Andy Goodrich: moved sc_process_b::reset_process() from header file |
| // to cpp file. Added dump_status() to print out the status of a |
| // process. |
| // |
| // Revision 1.10 2011/02/04 15:27:36 acg |
| // Andy Goodrich: changes for suspend-resume semantics. |
| // |
| // Revision 1.9 2011/02/01 21:06:12 acg |
| // Andy Goodrich: new layout for the process_state enum. |
| // |
| // Revision 1.8 2011/01/25 20:50:37 acg |
| // Andy Goodrich: changes for IEEE 1666 2011. |
| // |
| // Revision 1.7 2011/01/19 23:21:50 acg |
| // Andy Goodrich: changes for IEEE 1666 2011 |
| // |
| // Revision 1.6 2011/01/18 20:10:45 acg |
| // Andy Goodrich: changes for IEEE1666_2011 semantics. |
| // |
| // Revision 1.5 2010/07/22 20:02:33 acg |
| // Andy Goodrich: bug fixes. |
| // |
| // Revision 1.4 2009/05/22 16:06:29 acg |
| // Andy Goodrich: process control updates. |
| // |
| // Revision 1.3 2008/05/22 17:06:26 acg |
| // Andy Goodrich: updated copyright notice to include 2008. |
| // |
| // Revision 1.2 2007/09/20 20:32:35 acg |
| // Andy Goodrich: changes to the semantics of throw_it() to match the |
| // specification. A call to throw_it() will immediately suspend the calling |
| // thread until all the throwees have executed. At that point the calling |
| // thread will be restarted before the execution of any other threads. |
| // |
| // Revision 1.1.1.1 2006/12/15 20:20:05 acg |
| // SystemC 2.3 |
| // |
| // Revision 1.6 2006/04/20 17:08:17 acg |
| // Andy Goodrich: 3.0 style process changes. |
| // |
| // Revision 1.5 2006/04/11 23:13:21 acg |
| // Andy Goodrich: Changes for reduced reset support that only includes |
| // sc_cthread, but has preliminary hooks for expanding to method and thread |
| // processes also. |
| // |
| // Revision 1.4 2006/01/24 20:49:05 acg |
| // Andy Goodrich: changes to remove the use of deprecated features within the |
| // simulator, and to issue warning messages when deprecated features are used. |
| // |
| // Revision 1.3 2006/01/13 18:44:30 acg |
| // Added $Log to record CVS changes into the source. |
| // |