void sc_module::end_module() { if( ! m_end_module_called ) { /* TBD: Can check here to alert the user that end_module was not called for a previous module. */ (void)sc_get_curr_simcontext()->hierarchy_pop(); sc_get_curr_simcontext()->reset_curr_proc(); sensitive.reset(); sensitive_pos.reset(); sensitive_neg.reset(); m_end_module_called = true; m_module_name_p = 0; // make sure we are not called in ~sc_module(). } }
// +---------------------------------------------------------------------------- // |"sc_object_manager::create_name" // | // | This method creates a hierarchical name based on the name of the active // | object and the supplied leaf name. If the resultant name is not unique it // | will be made unique and a warning message issued. // | // | Arguments: // | leaf_name = name to use for the leaf of the hierarchy. // | Result is an std::string containing the name. // +---------------------------------------------------------------------------- std::string sc_object_manager::create_name(const char* leaf_name) { bool clash; // true if path name exists in obj table std::string leafname_string; // string containing the leaf name. std::string parentname_string; // parent path name sc_object* parent_p; // parent for this instance or NULL. std::string result_orig_string; // save for warning message. std::string result_string; // name to return. // CONSTRUCT PATHNAME TO THE NAME TO BE RETURNED: // // If there is not a leaf name generate one. parent_p = sc_get_curr_simcontext()->active_object(); parentname_string = parent_p ? parent_p->name() : ""; leafname_string = leaf_name; if (parent_p) { result_string = parentname_string; result_string += SC_HIERARCHY_CHAR; result_string += leafname_string; } else { result_string = leafname_string; } // SAVE the original path name result_orig_string = result_string; // MAKE SURE THE ENTITY NAME IS UNIQUE: // // If not use unique name generator to make it unique. clash = false; for (;;) { instance_table_t::iterator it = m_instance_table.find(result_string); if ( it == m_instance_table.end() || (it->second.m_event_p == NULL && it->second.m_object_p == NULL ) ) { break; } clash = true; leafname_string = sc_gen_unique_name(leafname_string.c_str(), false); if (parent_p) { result_string = parentname_string; result_string += SC_HIERARCHY_CHAR; result_string += leafname_string; } else { result_string = leafname_string; } } if (clash) { std::string message = result_orig_string; message += ". Latter declaration will be renamed to "; message += result_string; SC_REPORT_WARNING( SC_ID_INSTANCE_EXISTS_, message.c_str()); } return result_string; }
// +---------------------------------------------------------------------------- // |"sc_object::sc_object_init" // | // | This method initializes this object instance and places it in to the // | object hierarchy if the supplied name is not NULL. // | // | Arguments: // | nm = leaf name for the object. // +---------------------------------------------------------------------------- void sc_object::sc_object_init(const char* nm) { // SET UP POINTERS TO OBJECT MANAGER, PARENT, AND SIMULATION CONTEXT: // // Make the current simcontext the simcontext for this object m_simc = sc_get_curr_simcontext(); m_attr_cltn_p = 0; sc_object_manager* object_manager = m_simc->get_object_manager(); m_parent = m_simc->active_object(); // CONSTRUCT PATHNAME TO OBJECT BEING CREATED: // // If there is not a leaf name generate one. m_name = object_manager->create_name(nm ? nm : sc_object_newname().c_str()); // PLACE THE OBJECT INTO THE HIERARCHY IF A USER LEAF NAME WAS SUPPLIED: if ( nm != NULL && strncmp(nm, SC_KERNEL_MODULE_PREFIX, strlen(SC_KERNEL_MODULE_PREFIX)) ) { object_manager->insert_object(m_name, this); if ( m_parent ) m_parent->add_child_object( this ); else m_simc->add_child_object( this ); } }
void svf_thread_cond_sc::wait(svf_thread_mutex_sc *m) { // Expect mutex to be locked on entry wait_ev *waiter; if (m_freelist) { waiter = m_freelist; m_freelist = m_freelist->m_next; } else { waiter = new wait_ev(); } waiter->m_next = m_waiters; m_waiters = waiter; m->unlock(); // Wait sc_core::wait(waiter->m_ev, sc_get_curr_simcontext()); // Move the waiter to the freelist waiter->m_next = m_freelist; m_freelist = waiter; // Lock the mutex on the way out m->lock(); }
double sc_time::to_seconds() const { sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params; return ( sc_dt::uint64_to_double( m_value ) * time_params->time_resolution * 1e-15 ); }
bool sc_pending_activity_at_current_time() { sc_simcontext* c_p = sc_get_curr_simcontext(); return (c_p->m_delta_events.size() != 0) || !c_p->m_runnable->is_empty() || c_p->m_prim_channel_registry->pending_updates(); }
sc_module_name::sc_module_name( const char* name_ ) : m_name( name_ ), m_module_p( 0 ), m_next( 0 ), m_simc( sc_get_curr_simcontext() ), m_pushed( true ) { m_simc->get_object_manager()->push_module_name( this ); }
int sc_semaphore::wait() { while( in_use() ) { sc_core::wait( m_free, sc_get_curr_simcontext() ); } -- m_value; return 0; }
int sc_mutex::lock() { if ( m_owner == sc_get_current_process_b()) return 0; while( in_use() ) { sc_core::wait( m_free, sc_get_curr_simcontext() ); } m_owner = sc_get_current_process_b(); return 0; }
sc_trace_file_base::~sc_trace_file_base() { if( fp ) fclose(fp); #if SC_TRACING_PHASE_CALLBACKS_ == 0 // unregister from simcontext sc_get_curr_simcontext()->remove_trace_file( this ); #endif }
void uvm_ml_run_test(const std::vector<std::string>& tops, const char * test, const sc_time & duration) { int top_n = tops.size(); const char ** local_tops = new const char*[top_n]; for (int i = 0; i < top_n; ++i) { local_tops[i] = tops[i].c_str(); } BP(run_test)(framework_id, top_n, const_cast<char**>(local_tops), const_cast<char*>(test)); delete[] local_tops; sc_simcontext * context = sc_get_curr_simcontext(); context->co_simulate(duration); }
double sc_simulation_time() { static bool warn_simulation_time=true; if ( warn_simulation_time ) { warn_simulation_time=false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "sc_simulation_time() is deprecated use sc_time_stamp()" ); } return sc_get_curr_simcontext()->time_stamp().to_default_time_units(); }
void sc_cycle( const sc_time& duration ) { static bool warning_cycle = true; if ( warning_cycle ) { warning_cycle = false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "sc_cycle is deprecated: use sc_start(sc_time)" ); } sc_get_curr_simcontext()->cycle( duration ); }
void sc_initialize() { static bool warning_initialize = true; if ( warning_initialize ) { warning_initialize = false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "sc_initialize() is deprecated: use sc_start(SC_ZERO_TIME)" ); } sc_get_curr_simcontext()->initialize(); }
// 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; }
// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1 sc_process_b* sc_get_curr_process_handle() { static bool warn=true; if ( warn ) { warn = false; SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, "sc_get_curr_process_handle deprecated use sc_get_current_process_handle" ); } return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle; }
bool sc_writer_policy_check_port:: check_port( sc_object* target, sc_port_base * port_, bool is_output ) { if ( is_output && sc_get_curr_simcontext()->write_check() ) { // an out or inout port; only one can be connected if( m_output != 0) { sc_signal_invalid_writer( target, m_output, port_, false ); return false; } else { m_output = port_; } } return true; }
//------------------------------------------------------------------------------ //"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); } }
void REGFILE:: regfile_read_thread(void) { sc_uint<AWORDREG> a_wreg; sc_uint<AWORDREG> a_reg1; sc_uint<AWORDREG> a_reg2; sc_uint<DWORD> d_wreg; sc_uint<1> w_t; while (true) { #ifdef VERBOSE cerr << "REGFILE" << " Time is:" << sc_get_curr_simcontext()->time_stamp() << endl; #endif w_t = w.read(); if (w_t == 1) { a_wreg = w_addr_reg.read(); d_wreg = w_data_reg.read(); #ifdef VERBOSE cerr << "...writing $" << a_wreg << " = " << d_wreg << endl; #endif if (a_wreg < REGSIZE && a_wreg != 0) { rfile[a_wreg] = d_wreg; } } else{ a_reg1 = r_addr_reg1.read(); a_reg2 = r_addr_reg2.read(); r_data_reg1.write(rfile[a_reg1]); r_data_reg2.write(rfile[a_reg2]); #ifdef VERBOSE cerr << "...reading $" << a_reg1 << " = " << rfile[a_reg1] << " $" << a_reg2 << " = " << rfile[a_reg2] << endl; #endif } wait(); } }
void sc_start( const sc_time& duration ) { sc_simcontext* context; int status; context = sc_get_curr_simcontext(); status = context->sim_status(); if ( status != SC_SIM_OK ) { if ( status == SC_SIM_USER_STOP ) { SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_STOP_, ""); } return; } context->simulate( duration ); }
const char* sc_gen_unique_name( const char* basename_, bool preserve_first ) { 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_, preserve_first ); } else { sc_process_b* curr_proc_p = sc_get_current_process_b(); if ( curr_proc_p ) { return curr_proc_p->gen_unique_name( basename_, preserve_first ); } else { return simc->gen_unique_name( basename_, preserve_first ); } } }
bool sc_vector_base::check_init( size_type n ) const { if ( !n ) return false; if( size() ) // already filled { std::stringstream str; str << name() << ", size=" << size() << ", requested size=" << n; SC_REPORT_ERROR( SC_ID_VECTOR_INIT_CALLED_TWICE_ , str.str().c_str() ); return false; } sc_simcontext* simc = simcontext(); sc_assert( simc == sc_get_curr_simcontext() ); sc_object* parent_p = simc->get_object_manager()->hierarchy_curr(); if ( !parent_p ) parent_p = static_cast<sc_object*>( sc_get_current_process_b() ); if( parent_p != get_parent_object() ) { std::stringstream str; str << name() << ": expected " << ( get_parent_object() ? get_parent_object()->name() : "<top-level>" ) << ", got " << ( parent_p ? parent_p->name() : "<top-level>" ); SC_REPORT_ERROR( SC_ID_VECTOR_INIT_INVALID_CONTEXT_ , str.str().c_str() ); return false; } return true; }
const std::string sc_time::to_string() const { sc_dt::uint64 val = m_value; if( val == 0 ) { return std::string( "0 s" ); } sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params; sc_dt::uint64 tr = SCAST<sc_dt::int64>( time_params->time_resolution ); int n = 0; while( ( tr % 10 ) == 0 ) { tr /= 10; n ++; } assert( tr == 1 ); while( ( val % 10 ) == 0 ) { val /= 10; n ++; } char buf[BUFSIZ]; #if !defined( _MSC_VER ) std::sprintf( buf, "%llu", val ); #else std::sprintf( buf, "%I64u", val ); #endif std::string result( buf ); if( n >= 15 ) { for( int i = n - 15; i > 0; -- i ) { result += "0"; } result += " s"; } else { for( int i = n % 3; i > 0; -- i ) { result += "0"; } result += " "; result += time_units[n / 3]; } return result; }
sc_trace_file_base::sc_trace_file_base( const char* name, const char* extension ) : sc_trace_file() #if SC_TRACING_PHASE_CALLBACKS_ , sc_object( sc_gen_unique_name("$$$$kernel_tracefile$$$$") ) #endif , fp(0) , timescale_unit() , timescale_set_by_user(false) , filename_() , initialized_(false) , trace_delta_cycles_(false) { if( !name || !*name ) { SC_REPORT_ERROR( SC_ID_TRACING_FOPEN_FAILED_, "no name given" ); return; } else { std::stringstream ss; ss << name << "." << extension; ss.str().swap( filename_ ); } #if SC_TRACING_PHASE_CALLBACKS_ == 1 // remove from hierarchy sc_object::detach(); // register regular (non-delta) callbacks sc_object::register_simulation_phase_callback( // Note: Usually, one would expect to dump the initial values // of the traced variables at the end of the initialization // phase. The "non-callback" implementation dumps those // values only after the first delta cycle, though. // SC_END_OF_INITIALIZATION | SC_BEFORE_TIMESTEP | SC_PAUSED | SC_STOPPED ); #else // explicitly register with simcontext sc_get_curr_simcontext()->add_trace_file( this ); #endif }
//------------------------------------------------------------------------------ // Function: process_state_executing_nonruntime // // Parameters: //------------------------------------------------------------------------------ void uvm_common_phase::process_state_executing_nonruntime(sc_core::sc_module *pmod) { std::ostringstream outmsg; if (get_phase_type() != UVM_POSTRUN_PHASE) { // postrun phases are not generalized yet int result = do_execute(pmod); if (result && (CHECK_STOP_AT_PHASE_END() == true)) { SC_REPORT_INFO(UVM_PHASE_CTRL_STOP_USER, ""); #ifdef UVM_ML_PORTABLE // TODO - should be be incorporated into the phase controller instead? sc_get_curr_simcontext()->stop(); #endif // result = 0; } } else { uvm_component* pcomp = DCAST<uvm_component*>(pmod); if (pcomp != NULL) { if (_name.compare("final") == 0) pcomp->final_phase(this); else if (_name.compare("extract") == 0) pcomp->extract_phase(this); else if (_name.compare("check") == 0) pcomp->check_phase(this); else if (_name.compare("report") == 0) pcomp->report_phase(this); else { outmsg << _name << endl; SC_REPORT_FATAL(UVM_PHASE_UNKNOWN, outmsg.str().c_str()); exit(1); // TODO - is 'exit()' needed here after a FATAL? } } } }
int uvm_ml_tlm_rec::startup() { uvm_ml_utils::m_quasi_static_elaboration_started = true; sc_get_curr_simcontext()->quasi_static_start_of_construction(); return 1; }
const sc_time& sc_time_stamp() { return sc_get_curr_simcontext()->time_stamp(); }
void ghi() { sc_curr_proc_handle cpi = sc_get_curr_simcontext()->get_curr_proc_info(); cout << cpi->process_handle->name() << endl; }
void sc_object::sc_object_init(const char* nm) { bool clash; // True if path name exists in obj table const char* leafname_p; // Leaf name (this object) char pathname[BUFSIZ]; // Path name char pathname_orig[BUFSIZ]; // Original path name which may clash const char* parentname_p; // Parent path name bool put_in_table; // True if should put in object table // SET UP POINTERS TO OBJECT MANAGER, PARENT, AND SIMULATION CONTEXT: // // Make the current simcontext the simcontext for this object m_simc = sc_get_curr_simcontext(); m_attr_cltn_p = 0; sc_object_manager* object_manager = m_simc->get_object_manager(); sc_object* parent_p = object_manager->hierarchy_curr(); if (!parent_p) { sc_object* proc = (sc_object*)sc_get_current_process_b(); parent_p = proc; } m_parent = parent_p; // CONSTRUCT PATHNAME TO OBJECT BEING CREATED: // // If there is not a leaf name generate one. parentname_p = parent_p ? parent_p->name() : ""; if (nm && nm[0] ) { leafname_p = nm; put_in_table = true; } else { leafname_p = sc_object_newname(pathname_orig); put_in_table = false; } if (parent_p) { std::sprintf(pathname, "%s%c%s", parentname_p, SC_HIERARCHY_CHAR, leafname_p ); } else { strcpy(pathname, leafname_p); } // SAVE the original path name // strcpy(pathname_orig, pathname); // MAKE SURE THE OBJECT NAME IS UNIQUE // // If not use unique name generator to make it unique. clash = false; while (object_manager->find_object(pathname)) { clash = true; leafname_p = sc_gen_unique_name(leafname_p); if (parent_p) { std::sprintf(pathname, "%s%c%s", parentname_p, SC_HIERARCHY_CHAR, leafname_p ); } else { strcpy(pathname, leafname_p); } } if (clash) { std::string message = pathname_orig; message += ". Latter declaration will be renamed to "; message += pathname; SC_REPORT_WARNING( SC_ID_OBJECT_EXISTS_, message.c_str()); } // MOVE OBJECT NAME TO PERMANENT STORAGE // // Note here we pull a little trick -- use the first byte to store // information about whether to put the object in the object table in the // object manager char* ptr = new char[strlen( pathname ) + 2]; ptr[0] = put_in_table; m_name = ptr + 1; strcpy(m_name, pathname); if (put_in_table) { object_manager->insert_object(m_name, this); sc_module* curr_module = m_simc->hierarchy_curr(); if( curr_module != 0 ) { curr_module->add_child_object( this ); } else { sc_process_b* curr_proc = sc_get_current_process_b(); if (curr_proc) { curr_proc->add_child_object( this ); } else { m_simc->add_child_object( this ); } } } }
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