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 + -
显示快捷键?