void sc_simcontext::uvm_ml_quasi_static_start_of_simulation() { if( m_quasi_static_start_simulation_done || sim_status() != SC_SIM_OK ) { return; } m_execution_phase = phase_quasi_static_start_of_simulation; sc_cosim::do_ncsc_global_quasi_static_functions(ncsc_gf_phase_start_of_simulation); if (has_set_dpi_scope()) { sc_cosim::fpi().reset_dpi_export_scope(NULL); reset_dpi_scope(); } m_port_registry->quasi_static_start_simulation(); m_export_registry->quasi_static_start_simulation(); m_prim_channel_registry->quasi_static_start_simulation(); // m_module_registry->quasi_static_start_simulation(); if (has_set_dpi_scope()) { sc_cosim::fpi().reset_dpi_export_scope(NULL); reset_dpi_scope(); } m_quasi_static_start_simulation_done = true; m_ready_to_simulate = true; m_start_of_simulation_called = true; m_execution_phase = phase_unknown; // check for call(s) to sc_stop if( m_forced_stop ) { do_sc_stop_action(); return; } }
void sc_simcontext::initial_crunch( bool no_crunch ) { if ( no_crunch || m_runnable->is_empty() ) { return; } m_runnable->toggle(); // run the delta cycle loop crunch(); if ( m_error ) { return; } if ( m_something_to_trace ) { trace_cycle( false ); } // check for call(s) to sc_stop if ( m_forced_stop ) { do_sc_stop_action(); } }
bool sc_simcontext::signal_end_of_elaboration() { // SIGNAL THAT ELABORATION IS DONE // // We set the switch before the calls in case someone creates a process // in an end_of_elaboration callback. We need the information to flag // the process as being dynamic. m_elaboration_done = true; m_port_registry->elaboration_done(); m_export_registry->elaboration_done(); m_prim_channel_registry->elaboration_done(); if ( ! uvm_ml_sc_changes::sc_start_disabled ) { m_module_registry->elaboration_done(); } sc_reset::reconcile_resets(); // check for call(s) to sc_stop if( m_forced_stop ) { do_sc_stop_action(); return false; } return true; }
bool sc_simcontext::check_stop() { // check for call(s) to sc_stop if( m_forced_stop ) { do_sc_stop_action(); return true; } return false; }
void sc_simcontext::elaborate() { if ( m_elaboration_done || sim_status() != SC_SIM_OK ) { return; } m_port_registry->construction_done(); m_export_registry->construction_done(); m_prim_channel_registry->construction_done(); m_module_registry->construction_done(); // check for call(s) to sc_stop if ( m_forced_stop ) { do_sc_stop_action(); return; } // SIGNAL THAT ELABORATION IS DONE // // We set the switch before the calls in case someone creates a process // in an end_of_elaboration callback. We need the information to flag // the process as being dynamic. m_elaboration_done = true; m_port_registry->elaboration_done(); m_export_registry->elaboration_done(); m_prim_channel_registry->elaboration_done(); m_module_registry->elaboration_done(); sc_reset::reconcile_resets(); // check for call(s) to sc_stop if ( m_forced_stop ) { do_sc_stop_action(); return; } }
void sc_simcontext::stop() { static bool stop_warning_issued = false; if (m_forced_stop) { if ( !stop_warning_issued ) { stop_warning_issued = true; // This must be before the WARNING!!! SC_REPORT_WARNING(SC_ID_SIMULATION_STOP_CALLED_TWICE_, ""); } return; } if ( stop_mode == SC_STOP_IMMEDIATE ) m_runnable->init(); m_forced_stop = true; if ( !m_in_simulator_control ) { do_sc_stop_action(); } }
bool sc_simcontext::signal_start_of_simulation() { if (! m_start_of_simulation_called) { m_port_registry->start_simulation(); m_export_registry->start_simulation(); m_prim_channel_registry->start_simulation(); if ( ! uvm_ml_sc_changes::sc_start_disabled ) { m_module_registry->start_simulation(); } m_start_of_simulation_called = true; // CHECK FOR CALL(S) TO sc_stop if( m_forced_stop ) { do_sc_stop_action(); return false; } } return true; }
void sc_simcontext::simulate( const sc_time& duration ) { initialize( true ); if (sim_status() != SC_SIM_OK) { return; } sc_time non_overflow_time = sc_time(~sc_dt::UINT64_ZERO, false) - m_curr_time; if ( duration > non_overflow_time ) { SC_REPORT_ERROR(SC_ID_SIMULATION_TIME_OVERFLOW_, ""); return; } else if ( duration < SC_ZERO_TIME ) { SC_REPORT_ERROR(SC_ID_NEGATIVE_SIMULATION_TIME_,""); } m_in_simulator_control = true; sc_time until_t = m_curr_time + duration; m_until_event->cancel(); // to be on the safe side m_until_event->notify_internal( duration ); sc_time t; // IF DURATION WAS ZERO WE ONLY CRUNCH: // // We duplicate the code so that we don't add the overhead of the // check to each loop in the do below. if ( duration == SC_ZERO_TIME ) { m_runnable->toggle(); crunch( true ); if ( m_error ) return; if ( m_something_to_trace ) trace_cycle( /* delta cycle? */ false ); if ( m_forced_stop ) do_sc_stop_action(); return; } // NON-ZERO DURATION: EXECUTE UP TO THAT TIME: do { m_runnable->toggle(); crunch(); if ( m_error ) { m_in_simulator_control = false; return; } if ( m_something_to_trace ) { trace_cycle( false ); } // check for call(s) to sc_stop if ( m_forced_stop ) { do_sc_stop_action(); return; } do { t = next_time(); // PROCESS TIMED NOTIFICATIONS do { sc_event_timed* et = m_timed_events->extract_top(); sc_event* e = et->event(); delete et; if ( e != 0 ) { e->trigger(); } } while ( m_timed_events->size() && m_timed_events->top()->notify_time() == t ); } while ( m_runnable->is_empty() && t != until_t ); if ( t > m_curr_time ) m_curr_time = t; } while ( t != until_t ); m_in_simulator_control = false; }
void sc_simcontext::prepare_to_simulate() { sc_cthread_handle cthread_p; // Pointer to cthread process accessing. sc_method_handle method_p; // Pointer to method process accessing. sc_thread_handle thread_p; // Pointer to thread process accessing. if ( m_ready_to_simulate || sim_status() != SC_SIM_OK ) { return; } // instantiate the coroutine package # if defined(WIN32) m_cor_pkg = new sc_cor_pkg_fiber( this ); # else # if defined(SC_USE_PTHREADS) m_cor_pkg = new sc_cor_pkg_pthread( this ); # else m_cor_pkg = new sc_cor_pkg_qt( this ); # endif # endif m_cor = m_cor_pkg->get_main(); // NOTIFY ALL OBJECTS THAT SIMULATION IS ABOUT TO START: m_port_registry->start_simulation(); m_export_registry->start_simulation(); m_prim_channel_registry->start_simulation(); m_module_registry->start_simulation(); m_start_of_simulation_called = true; // CHECK FOR CALL(S) TO sc_stop if ( m_forced_stop ) { do_sc_stop_action(); return; } // PREPARE ALL (C)THREAD PROCESSES FOR SIMULATION: for ( thread_p = m_process_table->thread_q_head(); thread_p; thread_p = thread_p->next_exist() ) { thread_p->prepare_for_simulation(); } for ( cthread_p = m_process_table->cthread_q_head(); cthread_p; cthread_p = cthread_p->next_exist() ) { cthread_p->prepare_for_simulation(); } m_ready_to_simulate = true; m_runnable->init(); // update phase m_execution_phase = phase_update; m_prim_channel_registry->perform_update(); m_execution_phase = phase_notify; int size; // make all method processes runnable for ( method_p = m_process_table->method_q_head(); method_p; method_p = method_p->next_exist() ) { if ( !method_p->dont_initialize() ) { push_runnable_method_front( method_p ); } } // make all thread processes runnable for ( thread_p = m_process_table->thread_q_head(); thread_p; thread_p = thread_p->next_exist() ) { if ( !thread_p->dont_initialize() ) { push_runnable_thread_front( thread_p ); } } // process delta notifications if ( ( size = m_delta_events.size() ) != 0 ) { sc_event** l_delta_events = &m_delta_events[0]; int i = size - 1; do { l_delta_events[i]->trigger(); } while ( -- i >= 0 ); m_delta_events.resize(0); } // used in 'simulate()' m_until_event = new sc_event; if ( m_runnable->is_empty() ) { m_delta_count++; } }