//------------------------------------------------------------------------------ //"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; } }
void check_call_after_sim_start(std::string call_name) { std::string rpt_msg; if ( sc_get_status()&(SC_ELABORATION|SC_BEFORE_END_OF_ELABORATION|SC_END_OF_ELABORATION) ) { rpt_msg = call_name; //rpt_msg += name(); rpt_msg += " has to be called after simulation start."; SC_REPORT_ERROR("KisTA",rpt_msg.c_str()); } }
void check_call_at_elaboration(std::string call_name) { std::string rpt_msg; if ( !(sc_get_status()&SC_ELABORATION) ) { rpt_msg = call_name; //rpt_msg += name(); rpt_msg += " has to be called at elaboration time (before sc_start)."; SC_REPORT_ERROR("KisTA",rpt_msg.c_str()); } }
void check_call_before_sim_start(std::string call_name) { std::string rpt_msg; if ( sc_get_status()&(SC_START_OF_SIMULATION|SC_RUNNING|SC_STOPPED|SC_PAUSED|SC_END_OF_SIMULATION) ) { rpt_msg = call_name; //rpt_msg += name(); rpt_msg += " has to be called before simulation start."; SC_REPORT_ERROR("KisTA",rpt_msg.c_str()); } }
//------------------------------------------------------------------------------ //"sc_method_process::kill_process" // // This method removes throws a kill for this object instance. It calls the // sc_process_b::kill_process() method to perform low level clean up. //------------------------------------------------------------------------------ void sc_method_process::kill_process(sc_descendant_inclusion_info descendants) { // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR: if ( sc_get_status() == SC_ELABORATION ) { report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ ); } // IF NEEDED, PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS: 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->kill_process(descendants); } } // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE // IGNORE THE KILL: if ( m_unwinding ) { SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() ); return; } if ( m_state & ps_bit_zombie ) return; // REMOVE OUR PROCESS FROM EVENTS, ETC., AND IF ITS THE ACTIVE PROCESS // THROW ITS KILL. // // Note we set the throw status to kill regardless if we throw or not. // That lets check_for_throws stumble across it if we were in the call // chain when the kill call occurred. if ( next_runnable() != 0 ) simcontext()->remove_runnable_method( this ); disconnect_process(); m_throw_status = THROW_KILL; if ( sc_get_current_process_b() == this ) { throw sc_unwind_exception( this, false ); } }
//------------------------------------------------------------------------------ //"sc_method_process::throw_user" // // This virtual method is invoked when a user exception is to be thrown. // If requested it will also throw the exception to the children of this // object instance. Since this is a method no throw will occur for this // object instance. The children will be awakened from youngest child to // eldest. // helper_p -> object to use to throw the exception. // descendants = indicator of whether this process' children should also // be suspended //------------------------------------------------------------------------------ void sc_method_process::throw_user( const sc_throw_it_helper& helper, sc_descendant_inclusion_info descendants ) { // IF THE SIMULATION IS NOT ACTUALLY RUNNING THIS IS AN ERROR: if ( sc_get_status() != SC_RUNNING ) { report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ ); } // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS: 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 ) { DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on"); child_p->throw_user(helper, descendants); } } } #if 0 // shouldn't we throw, if we're currently running? if ( sc_get_current_process_b() == (sc_process_b*)this ) { remove_dynamic_events(); m_throw_status = THROW_USER; if ( m_throw_helper_p != 0 ) delete m_throw_helper_p; m_throw_helper_p = helper.clone(); m_throw_helper_p->throw_it(); } // throw_it HAS NO EFFECT ON A METHOD, ISSUE A WARNING: else #endif { SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() ); } }