//------------------------------------------------------------------------------ //"sc_process_b::reset_changed" // // This method is called when there is a change in the value of the // signal that was specified via reset_signal_is, or the value of the // m_sticky_reset field. We get called any time m_sticky_reset changes // or a signal value changes since, since we may need to throw an exception // or clear one. Note that this method may be called when there is no // active process, but rather the main simulator is executing so we must // check for that case. // // Arguments: // async = true if this is an asynchronous reset. // asserted = true if reset being asserted, false if being deasserted. //------------------------------------------------------------------------------ void sc_process_b::reset_changed( bool async, bool asserted ) { // Error out on the corner case: if ( !sc_allow_process_control_corners && !async && (m_state & ps_bit_suspended) ) { report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_, "synchronous reset changed on a suspended process" ); } // IF THIS OBJECT IS PUSHING UP DAISIES WE ARE DONE: if ( m_state & ps_bit_zombie ) return; // Reset is being asserted: if ( asserted ) { // if ( m_reset_event_p ) m_reset_event_p->notify(); if ( async ) { m_active_areset_n++; if ( sc_is_running() ) throw_reset(true); } else { m_active_reset_n++; if ( sc_is_running() ) throw_reset(false); } } // Reset is being deasserted: else { if ( async ) { m_active_areset_n--; } else { m_active_reset_n--; } } // Clear the throw type if there are no active resets. if ( (m_throw_status == THROW_SYNC_RESET || m_throw_status == THROW_ASYNC_RESET) && m_active_areset_n == 0 && m_active_reset_n == 0 && !m_sticky_reset ) { m_throw_status = THROW_NONE; } }
//------------------------------------------------------------------------------ //"sc_method_process::sc_method_process" // // This is the object instance constructor for this class. //------------------------------------------------------------------------------ sc_method_process::sc_method_process( const char* name_p, bool free_host, SC_ENTRY_FUNC method_p, sc_process_host* host_p, const sc_spawn_options* opt_p ): sc_process_b( name_p && name_p[0] ? name_p : sc_gen_unique_name("method_p"), free_host, method_p, host_p, opt_p) { // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMUALTION HAS STARTED: if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() ) { SC_REPORT_ERROR( SC_ID_MODULE_METHOD_AFTER_START_, "" ); } // INITIALIZE VALUES: // // If there are spawn options use them. m_process_kind = SC_METHOD_PROC_; if (opt_p) { m_dont_init = opt_p->m_dont_initialize; // traverse event sensitivity list for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) { sc_sensitive::make_static_sensitivity( this, *opt_p->m_sensitive_events[i]); } // traverse port base sensitivity list for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++) { sc_sensitive::make_static_sensitivity( this, *opt_p->m_sensitive_port_bases[i]); } // traverse interface sensitivity list for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++) { sc_sensitive::make_static_sensitivity( this, *opt_p->m_sensitive_interfaces[i]); } // traverse event finder sensitivity list for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size(); i++) { sc_sensitive::make_static_sensitivity( this, *opt_p->m_sensitive_event_finders[i]); } } else { m_dont_init = false; } }
void sc_port_registry::insert( sc_port_base* port_ ) { if( sc_is_running() ) { port_->report_error( SC_ID_INSERT_PORT_, "simulation running" ); return; } if( m_simc->elaboration_done() ) { port_->report_error( SC_ID_INSERT_PORT_, "elaboration done" ); return; } #if defined(DEBUG_SYSTEMC) // check if port_ is already inserted for( int i = size() - 1; i >= 0; -- i ) { if( port_ == m_port_vec[i] ) { port_->report_error( SC_ID_INSERT_PORT_, "port already inserted" ); return; } } #endif // append the port to the current module's vector of ports sc_module* curr_module = m_simc->hierarchy_curr(); if( curr_module == 0 ) { port_->report_error( SC_ID_PORT_OUTSIDE_MODULE_ ); return; } curr_module->append_port( port_ ); // insert m_port_vec.push_back( port_ ); }
sc_process_handle sc_get_current_process_handle() { return ( sc_is_running() ) ? sc_process_handle(sc_get_current_process_b()) : sc_get_last_created_process_handle(); }
// not documented, but available const std::string sc_report_compose_message(const sc_report& rep) { static const char * severity_names[] = { "Info", "Warning", "Error", "Fatal" }; std::string str; str += severity_names[rep.get_severity()]; str += ": "; if ( rep.get_id() >= 0 ) // backward compatibility with 2.0+ { char idstr[64]; std::sprintf(idstr, "(%c%d) ", "IWEF"[rep.get_severity()], rep.get_id()); str += idstr; } str += rep.get_msg_type(); if ( *rep.get_msg() ) { str += ": "; str += rep.get_msg(); } if ( rep.get_severity() > SC_INFO ) { char line_number_str[16]; str += "\nIn file: "; str += rep.get_file_name(); str += ":"; std::sprintf(line_number_str, "%d", rep.get_line_number()); str += line_number_str; sc_simcontext* simc = sc_get_curr_simcontext(); if ( simc && sc_is_running() ) { const char* proc_name = rep.get_process_name(); if ( proc_name ) { str += "\nIn process: "; str += proc_name; str += " @ "; str += rep.get_time().to_string(); } } } return str; }
//------------------------------------------------------------------------------ //"sc_method_process::disable_process" // // This virtual method disables this process and its children if requested to. // descendants = indicator of whether this process' children should also // be suspended //------------------------------------------------------------------------------ void sc_method_process::disable_process( sc_descendant_inclusion_info descendants ) { // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS: if ( descendants == SC_INCLUDE_DESCENDANTS ) { const std::vector<sc_object*>& children = get_child_objects(); int child_n = children.size(); for ( int child_i = 0; child_i < child_n; child_i++ ) { sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]); if ( child_p ) child_p->disable_process(descendants); } } // DON'T ALLOW CORNER CASE BY DEFAULT: if ( !sc_allow_process_control_corners ) { switch( m_trigger_type ) { case AND_LIST_TIMEOUT: case EVENT_TIMEOUT: case OR_LIST_TIMEOUT: case TIMEOUT: report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_, "attempt to disable a method with timeout wait" ); break; default: break; } } // DISABLE OUR OBJECT INSTANCE: m_state = m_state | ps_bit_disabled; // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE METHOD: if ( !sc_is_running() ) { sc_get_curr_simcontext()->remove_runnable_method(this); } }
//------------------------------------------------------------------------------ //"sc_set_stop_mode" // // This function sets the mode of operation when sc_stop() is called. // mode = SC_STOP_IMMEDIATE or SC_STOP_FINISH_DELTA. //------------------------------------------------------------------------------ void sc_set_stop_mode(sc_stop_mode mode) { if ( sc_is_running() ) { SC_REPORT_WARNING(SC_ID_STOP_MODE_AFTER_START_,""); } else { switch ( mode ) { case SC_STOP_IMMEDIATE: case SC_STOP_FINISH_DELTA: stop_mode = mode; break; default: break; } } }
void sc_module::set_stack_size( std::size_t size ) { sc_process_handle proc_h( sc_is_running() ? sc_get_current_process_handle() : sc_get_last_created_process_handle() ); sc_thread_handle thread_h; // Current process as thread. thread_h = (sc_thread_handle)proc_h; if ( thread_h ) { thread_h->set_stack_size( size ); } else { SC_REPORT_WARNING( SC_ID_SET_STACK_SIZE_, 0 ); } }
void sc_module_registry::insert( sc_module& module_ ) { if( sc_is_running() ) { SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "simulation running" ); } if( m_simc->elaboration_done() ) { SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "elaboration done" ); } #ifdef DEBUG_SYSTEMC // check if module_ is already inserted for( int i = size() - 1; i >= 0; -- i ) { if( &module_ == m_module_vec[i] ) { SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "already inserted" ); } } #endif // insert m_module_vec.push_back( &module_ ); }
void sc_set_time_resolution( double v, sc_time_unit tu ) { // first perform the necessary checks // must be positive if( v < 0.0 ) { SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value not positive" ); } // must be a power of ten double dummy; #if defined( __HP_aCC ) || defined(__ppc__) // aCC seems to have a bug in modf() if( modf( log10( v < 1.0 ? 1.0/v : v ), &dummy ) != 0.0 ) { #else if( modf( log10( v ), &dummy ) != 0.0 ) { #endif SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value not a power of ten" ); } sc_simcontext* simc = sc_get_curr_simcontext(); // can only be specified during elaboration if( sc_is_running() ) { SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "simulation running" ); } sc_time_params* time_params = simc->m_time_params; // can be specified only once if( time_params->time_resolution_specified ) { SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "already specified" ); } // can only be specified before any sc_time is constructed if( time_params->time_resolution_fixed ) { SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "sc_time object(s) constructed" ); } // must be larger than or equal to 1 fs volatile double resolution = v * time_values[tu]; if( resolution < 1.0 ) { SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value smaller than 1 fs" ); } // recalculate the default time unit volatile double time_unit = sc_dt::uint64_to_double( time_params->default_time_unit ) * ( time_params->time_resolution / resolution ); if( time_unit < 1.0 ) { SC_REPORT_WARNING( SC_ID_DEFAULT_TIME_UNIT_CHANGED_, 0 ); time_params->default_time_unit = 1; } else { time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit ); } time_params->time_resolution = resolution; time_params->time_resolution_specified = true; } sc_time sc_get_time_resolution() { return sc_time( sc_dt::UINT64_ONE, false ); } void sc_set_default_time_unit( double v, sc_time_unit tu ) { static bool warn_default_time_unit=true; if ( warn_default_time_unit ) { warn_default_time_unit=false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "deprecated function: sc_set_default_time_unit"); } // first perform the necessary checks // must be positive if( v < 0.0 ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive" ); } // must be a power of ten double dummy; if( modf( log10( v ), &dummy ) != 0.0 ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value not a power of ten" ); } sc_simcontext* simc = sc_get_curr_simcontext(); // can only be specified during elaboration if( sc_is_running() ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running" ); } sc_time_params* time_params = simc->m_time_params; // can only be specified before any sc_time is constructed if( time_params->time_resolution_fixed ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "sc_time object(s) constructed" ); } // can be specified only once if( time_params->default_time_unit_specified ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified" ); } // must be larger than or equal to the time resolution volatile double time_unit = ( v * time_values[tu] ) / time_params->time_resolution; if( time_unit < 1.0 ) { SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value smaller than time resolution" ); } time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit ); time_params->default_time_unit_specified = true; } sc_time sc_get_default_time_unit() { bool warn_get_default_time_unit = true; if ( warn_get_default_time_unit ) { warn_get_default_time_unit=false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "deprecated function: sc_get_default_time_unit"); } return sc_time( sc_get_curr_simcontext()->m_time_params->default_time_unit, false ); } // ---------------------------------------------------------------------------- const sc_time SC_ZERO_TIME; } // namespace sc_core