⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc_simcontext.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 3 页
字号:
sc_simcontext::sc_simcontext(){    init();}sc_simcontext::~sc_simcontext(){    clean();}inline voidsc_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();    } }inlinevoidsc_simcontext::cycle( const sc_time& t){    sc_time next_event_time;    m_in_simulator_control = true;    m_runnable->toggle();    crunch();     trace_cycle( /* delta cycle? */ false );    m_curr_time += t;    next_event_time = next_time();    if ( next_event_time != SC_ZERO_TIME && next_event_time <= m_curr_time) {        SC_REPORT_WARNING(SC_ID_CYCLE_MISSES_EVENTS_, "");    }    m_in_simulator_control = false;}voidsc_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;    }}voidsc_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++;    }}voidsc_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();    }}voidsc_simcontext::initialize( bool no_crunch ){    m_in_simulator_control = true;    elaborate();    prepare_to_simulate();    initial_crunch(no_crunch);    m_in_simulator_control = false;}voidsc_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;}voidsc_simcontext::do_sc_stop_action(){    ::std::cout << "SystemC: simulation stopped by user." << ::std::endl;    if (m_start_of_simulation_called) {	end();	m_in_simulator_control = false;    }}//------------------------------------------------------------------------------//"sc_simcontext::stop"//// This method stops the simulator after some amount of further processing.// How much processing is done depends upon the value of the global variable// stop_mode://     SC_STOP_IMMEDIATE - aborts the execution phase of the current delta//                         cycle and performs whatever updates are pending.//     SC_STOP_FINISH_DELTA - finishes the current delta cycle - both execution//                            and updates.// If sc_stop is called outside of the purview of the simulator kernel // (e.g., directly from sc_main), the end of simulation notifications // are performed. From within the purview of the simulator kernel, these// will be performed at a later time.//------------------------------------------------------------------------------voidsc_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();    } }voidsc_simcontext::reset(){    clean();    init();}voidsc_simcontext::end(){    m_ready_to_simulate = false;    m_port_registry->simulation_done();    m_export_registry->simulation_done();    m_prim_channel_registry->simulation_done();    m_module_registry->simulation_done();    m_end_of_simulation_called = true;}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{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -