sc_cor* sc_simcontext::next_cor() { if( m_error ) { return m_cor; } sc_thread_handle thread_h = pop_runnable_thread(); while( thread_h != 0 ) { if ( thread_h->ready_to_run() ) break; thread_h = pop_runnable_thread(); } if( thread_h != 0 ) { return thread_h->m_cor_p; } else { return m_cor; } }
inline void sc_simcontext::crunch( bool once ) { #ifdef DEBUG_SYSTEMC int num_deltas = 0; // number of delta cycles #endif while ( true ) { // EVALUATE PHASE m_execution_phase = phase_evaluate; while ( true ) { // execute method processes sc_method_handle method_h = pop_runnable_method(); while ( method_h != 0 ) { try { method_h->semantics(); } catch ( const sc_report& ex ) { ::std::cout << "\n" << ex.what() << ::std::endl; m_error = true; return; } method_h = pop_runnable_method(); } // execute (c)thread processes sc_thread_handle thread_h = pop_runnable_thread(); while ( thread_h != 0 ) { if ( thread_h->ready_to_run() ) break; thread_h = pop_runnable_thread(); } if ( thread_h != 0 ) { m_cor_pkg->yield( thread_h->m_cor_p ); } if ( m_error ) { return; } // check for call(s) to sc_stop if ( m_forced_stop ) { if ( stop_mode == SC_STOP_IMMEDIATE ) return; } if ( m_runnable->is_empty() ) { // no more runnable processes break; } m_runnable->toggle(); } // UPDATE PHASE // // The delta count must be updated first so that event_occurred() // will work. m_execution_phase = phase_update; m_delta_count ++; m_prim_channel_registry->perform_update(); m_execution_phase = phase_notify; if ( m_something_to_trace ) { trace_cycle( /* delta cycle? */ true ); } // m_delta_count ++; // check for call(s) to sc_stop if ( m_forced_stop ) { break; } #ifdef DEBUG_SYSTEMC // check for possible infinite loops if ( ++ num_deltas > SC_MAX_NUM_DELTA_CYCLES ) { ::std::cerr << "SystemC warning: " << "the number of delta cycles exceeds the limit of " << SC_MAX_NUM_DELTA_CYCLES << ", defined in sc_constants.h.\n" << "This is a possible sign of an infinite loop.\n" << "Increase the limit if this warning is invalid.\n"; break; } #endif // PROCESS DELTA NOTIFICATIONS: int size = m_delta_events.size(); if ( size != 0 ) { sc_event** l_events = &m_delta_events[0]; int i = size - 1; do { l_events[i]->trigger(); } while ( -- i >= 0 ); m_delta_events.resize(0); } if ( m_runnable->is_empty() ) { // no more runnable processes break; } // IF ONLY DOING ONE CYCLE, WE ARE DONE. OTHERWISE GET NEW CALLBACKS if ( once ) break; m_runnable->toggle(); } }