//------------------------------------------------------------------------------
//"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;
    }
}
Пример #2
0
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());
	}
}
Пример #3
0
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());
	}
}
Пример #4
0
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());
	}	
}
Пример #5
0
//------------------------------------------------------------------------------
//"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 );
    }
}
Пример #6
0
//------------------------------------------------------------------------------
//"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() );
   }


}