sc_simcontext.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 925 行 · 第 1/2 页
CPP
925 行
voidsc_simcontext::simulate( const sc_time& duration ){ initialize( true ); if( sim_status() != SC_SIM_OK ) { return; } sc_time until_t = ( duration == SC_ZERO_TIME ) ? sc_time( ~sc_dt::UINT64_ZERO, false ) // max time : m_curr_time + duration; m_until_event->cancel(); // to be on the safe side m_until_event->notify_delayed( until_t - m_curr_time ); sc_time t; do { m_runnable->toggle(); crunch(); if( m_error ) { return; } if( m_something_to_trace ) { trace_cycle( /* delta cycle? */ false ); } // check for call(s) to sc_stop if( m_forced_stop ) { cout << "SystemC: simulation stopped by user." << endl; 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->push_empty() && t != until_t ); m_curr_time = t; } while( t != until_t );}voidsc_simcontext::stop(){ m_forced_stop = true;}voidsc_simcontext::reset(){ clean(); init();}voidsc_simcontext::hierarchy_push( sc_module* mod ){ m_object_manager->hierarchy_push( mod );}sc_module*sc_simcontext::hierarchy_pop(){ return DCAST<sc_module*>( m_object_manager->hierarchy_pop() );}sc_module*sc_simcontext::hierarchy_curr() const{ return DCAST<sc_module*>( m_object_manager->hierarchy_curr() );} sc_object*sc_simcontext::first_object(){ return m_object_manager->first_object();}sc_object*sc_simcontext::next_object(){ return m_object_manager->next_object();}sc_object*sc_simcontext::find_object( const char* name ){ return m_object_manager->find_object( name );}// to generate unique names for objects in an MT-Safe wayconst char*sc_simcontext::gen_unique_name( const char* basename_ ){ return m_name_gen->gen_unique_name( basename_ );}sc_method_handlesc_simcontext::register_method_process( const char* name, SC_ENTRY_FUNC entry_fn, sc_module* module ){ sc_method_handle handle = new sc_method_process( name, entry_fn, module ); m_process_table->push_back( handle ); set_curr_proc( handle ); return handle;}sc_thread_handlesc_simcontext::register_thread_process( const char* name, SC_ENTRY_FUNC entry_fn, sc_module* module ){ sc_thread_handle handle = new sc_thread_process( name, entry_fn, module ); m_process_table->push_back( handle ); set_curr_proc( handle ); return handle;}sc_cthread_handlesc_simcontext::register_cthread_process( const char* name, SC_ENTRY_FUNC entry_fn, sc_module* module ){ sc_cthread_handle handle = new sc_cthread_process( name, entry_fn, module ); m_process_table->push_back( handle ); set_curr_proc( handle ); return handle;}voidsc_simcontext::add_trace_file( sc_trace_file* tf ){ m_trace_files.push_back( tf ); m_something_to_trace = true;}sc_cor*sc_simcontext::next_cor(){ if( m_error ) { return m_cor; } sc_thread_handle thread_h = pop_runnable_thread(); while( thread_h != 0 && ! thread_h->ready_to_run() ) { thread_h = pop_runnable_thread(); } if( thread_h != 0 ) { return thread_h->m_cor; } else { return m_cor; }}const sc_pvector<sc_object*>&sc_simcontext::get_child_objects() const{ return m_child_objects;}voidsc_simcontext::add_child_object( sc_object* object_ ){ // no check if object_ is already in the set m_child_objects.push_back( object_ );}voidsc_simcontext::remove_child_object( sc_object* object_ ){ int size = m_child_objects.size(); for( int i = 0; i < size; ++ i ) { if( object_ == m_child_objects[i] ) { m_child_objects[i] = m_child_objects[size - 1]; m_child_objects.decr_count(); return; } } // no check if object_ is really in the set}voidsc_simcontext::crunch(){#ifdef DEBUG_SYSTEMC int num_deltas = 0; // number of delta cycles#endif m_delta_count ++; while( true ) { // EVALUATE PHASE while( true ) { // execute method processes sc_method_handle method_h = pop_runnable_method(); while( method_h != 0 ) { try { method_h->execute(); } catch( const sc_exception& ex ) { cout << "\n" << ex.what() << 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 && ! thread_h->ready_to_run() ) { thread_h = pop_runnable_thread(); } if( thread_h != 0 ) { m_cor_pkg->yield( thread_h->m_cor ); } if( m_error ) { return; } // check for call(s) to sc_stop if( m_forced_stop ) { break; } if( m_runnable->push_empty() ) { // no more runnable processes break; } m_runnable->toggle(); } // UPDATE PHASE m_update_phase = true; m_prim_channel_registry->perform_update(); m_update_phase = false; 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 ) { 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; if( ( size = m_delta_events.size() ) == 0 ) { break; } sc_event** l_events = m_delta_events.raw_data(); int i = size - 1; do { l_events[i]->trigger(); } while( -- i >= 0 ); m_delta_events.erase_all(); if( m_runnable->push_empty() ) { // no more runnable processes break; } m_runnable->toggle(); }}const sc_timesc_simcontext::next_time(){ while( m_timed_events->size() ) { sc_event_timed* et = m_timed_events->top(); if( et->event() != 0 ) { return et->notify_time(); } delete m_timed_events->extract_top(); } return SC_ZERO_TIME;}voidsc_simcontext::remove_delta_event( sc_event* e ){ int i = e->m_delta; int j = m_delta_events.size() - 1; assert( i >= 0 && i <= j ); if( i != j ) { sc_event** l_delta_events = m_delta_events.raw_data(); l_delta_events[i] = l_delta_events[j]; l_delta_events[i]->m_delta = i; } m_delta_events.decr_count(); e->m_delta = -1;}voidsc_simcontext::trace_cycle( bool delta_cycle ){ int size; if( ( size = m_trace_files.size() ) != 0 ) { sc_trace_file** l_trace_files = m_trace_files.raw_data(); int i = size - 1; do { l_trace_files[i]->cycle( delta_cycle ); } while( -- i >= 0 ); }}// ----------------------------------------------------------------------------// Not MT-safe!static sc_simcontext* sc_curr_simcontext = 0;sc_simcontext*sc_get_curr_simcontext(){ if( sc_curr_simcontext == 0 ) {#ifdef PURIFY static sc_simcontext sc_default_global_context; sc_curr_simcontext = &sc_default_global_context;#else static sc_simcontext* sc_default_global_context = new sc_simcontext; sc_curr_simcontext = sc_default_global_context;#endif } return sc_curr_simcontext;}// Generates unique names within each module.const char*sc_gen_unique_name( const char* basename_ ){ sc_simcontext* simc = sc_get_curr_simcontext(); sc_module* curr_module = simc->hierarchy_curr(); if( curr_module != 0 ) { return curr_module->gen_unique_name( basename_ ); } else { return simc->gen_unique_name( basename_ ); }}// Set the random seed for controlled randomization -- not yet implementedvoidsc_set_random_seed( unsigned int ){ SC_REPORT_WARNING( SC_ID_NOT_IMPLEMENTED_, "void sc_set_random_seed( unsigned int )" );}voidsc_start( const sc_time& duration ){ sc_get_curr_simcontext()->simulate( duration );}voidsc_stop(){ sc_get_curr_simcontext()->stop();}voidsc_initialize(){ sc_get_curr_simcontext()->initialize();}voidsc_cycle( const sc_time& duration ){ sc_get_curr_simcontext()->cycle( duration );}const sc_time&sc_time_stamp(){ return sc_get_curr_simcontext()->time_stamp();}doublesc_simulation_time(){ return sc_get_curr_simcontext()->time_stamp().to_default_time_units();}voidsc_defunct_process_function( sc_module* ){ // This function is pointed to by defunct sc_thread_process'es and // sc_cthread_process'es. In a correctly constructed world, this // function should never be called; hence the assert. assert( false );}// Taf!
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?