sc_port.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 701 行 · 第 1/2 页
CPP
701 行
}// support methodsintsc_port_base::first_parent(){ for( int i = 0; i < m_bind_info->size(); ++ i ) { if( m_bind_info->vec[i]->parent != 0 ) { return i; } } return -1;}voidsc_port_base::insert_parent( int i ){ sc_pvector<sc_bind_elem*>& vec = m_bind_info->vec; this_type* parent = vec[i]->parent; vec[i]->iface = parent->m_bind_info->vec[0]->iface; vec[i]->parent = 0; int n = parent->m_bind_info->size() - 1; if( n > 0 ) { if( m_bind_info->size() + n > m_bind_info->max_size && m_bind_info->max_size > 0 ) { report_error( SC_ID_COMPLETE_BINDING_, "maximum reached" ); } // resize the bind vector (by adding new elements) for( int k = 0; k < n; ++ k ) { vec.push_back( new sc_bind_elem() ); } // move elements in the bind vector for( int k = m_bind_info->size() - n - 1; k > i; -- k ) { vec[k + n]->iface = vec[k]->iface; vec[k + n]->parent = vec[k]->parent; } // insert parent interfaces into the bind vector for( int k = i + 1; k <= i + n; ++ k ) { vec[k]->iface = parent->m_bind_info->vec[k - i]->iface; vec[k]->parent = 0; } }}// called when elaboration is donevoidsc_port_base::complete_binding(){ assert( m_bind_info != 0 ); if( m_bind_info->complete ) { return; } if( m_bind_info->size() == 0 ) { report_error( SC_ID_COMPLETE_BINDING_, "port not bound" ); } int i = first_parent(); while( i >= 0 ) { m_bind_info->vec[i]->parent->complete_binding(); insert_parent( i ); i = first_parent(); } int size; for( int j = 0; j < m_bind_info->size(); ++ j ) { sc_interface* iface = m_bind_info->vec[j]->iface; // check the state if( iface == 0 || m_bind_info->vec[j]->parent != 0 ) { report_error( SC_ID_COMPLETE_BINDING_, "inconsistent state" ); } if( j > m_bind_info->last_add ) { // add (cache) the interface add_interface( iface ); } if( m_bind_info->is_leaf ) { // only register "leaf" ports (ports without children) iface->register_port( *this, if_typename() ); } // complete static sensitivity for methods size = m_bind_info->method_vec.size(); for( int k = 0; k < size; ++ k ) { sc_bind_ef* p = m_bind_info->method_vec[k]; const sc_event& event = ( p->event_finder != 0 ) ? p->event_finder->find_event() : iface->default_event(); p->handle->add_static_event( event ); } // complete static sensitivity for threads size = m_bind_info->thread_vec.size(); for( int k = 0; k < size; ++ k ) { sc_bind_ef* p = m_bind_info->thread_vec[k]; const sc_event& event = ( p->event_finder != 0 ) ? p->event_finder->find_event() : iface->default_event(); p->handle->add_static_event( event ); } } // cleanup size = m_bind_info->method_vec.size(); for( int k = 0; k < size; ++ k ) { delete m_bind_info->method_vec[k]; } m_bind_info->method_vec.erase_all(); size = m_bind_info->thread_vec.size(); for( int k = 0; k < size; ++ k ) { delete m_bind_info->thread_vec[k]; } m_bind_info->thread_vec.erase_all(); m_bind_info->complete = true;}voidsc_port_base::elaboration_done(){ assert( m_bind_info != 0 && m_bind_info->complete ); delete m_bind_info; m_bind_info = 0; end_of_elaboration();}// ----------------------------------------------------------------------------// CLASS : sc_port_registry//// Registry for all ports.// FOR INTERNAL USE ONLY!// ----------------------------------------------------------------------------voidsc_port_registry::insert( sc_port_base* port_ ){ if( m_simc->is_running() ) { port_->report_error( SC_ID_INSERT_PORT_, "simulation running" ); }#ifdef 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" ); } }#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_ ); } curr_module->append_port( port_ ); // insert m_port_vec.push_back( port_ );}voidsc_port_registry::remove( sc_port_base* port_ ){ int i; for( i = size() - 1; i >= 0; -- i ) { if( port_ == m_port_vec[i] ) { break; } } if( i == -1 ) { port_->report_error( SC_ID_REMOVE_PORT_, "port not registered" ); } // remove m_port_vec[i] = m_port_vec[size() - 1]; m_port_vec.decr_count();}voidsc_port_registry::add_lambda_for_resolution( const sc_lambda_ptr& lambda_ ){ sc_lambda_ptr* lambda_copy = new sc_lambda_ptr( lambda_ ); m_unresolved_lambdas->push_back( lambda_copy );}// constructorsc_port_registry::sc_port_registry( sc_simcontext& simc_ ): m_simc( &simc_ ){ m_unresolved_lambdas = new sc_pvector<sc_lambda_ptr*>;}// destructorsc_port_registry::~sc_port_registry(){ delete_unresolved_lambdas();}// called when elaboration is donevoidsc_port_registry::elaboration_done(){ for( int i = size() - 1; i >= 0; -- i ) { m_port_vec[i]->complete_binding(); } resolve_lambdas(); for( int i = size() - 1; i >= 0; -- i ) { m_port_vec[i]->elaboration_done(); }}voidsc_port_registry::resolve_lambdas(){ int sz = m_unresolved_lambdas->size(); for( int i = 0; i < sz; ++ i ) { sc_lambda_ptr* lambda_copy = m_unresolved_lambdas->fetch( i ); (*lambda_copy)->replace_ports( &replace_port, this ); } delete_unresolved_lambdas();}voidsc_port_registry::delete_unresolved_lambdas(){ if( m_unresolved_lambdas != 0 ) { int sz = m_unresolved_lambdas->size(); for( int i = 0; i < sz; ++ i ) { delete m_unresolved_lambdas->fetch( i ); } delete m_unresolved_lambdas; m_unresolved_lambdas = 0; }}// This is a static member function.voidsc_port_registry::replace_port( sc_port_registry* registry, sc_lambda_rand* rand ){ switch( rand->rand_ty ) { case SC_LAMBDA_RAND_SIGNAL_BOOL: { // the tricky part, reversed const sc_port_base* pb = RCAST<const sc_port_base*>( rand->edgy_sig ); // check if pb is a port bool is_port = false; for( int i = registry->size() - 1; i >= 0; -- i ) { if( pb == registry->m_port_vec[i] ) { is_port = true; break; } } if( ! is_port ) { break; } // cast pb to the appropriate port type const sc_port_b<sc_signal_in_if<bool> >* in_port = DCAST<const sc_port_b<sc_signal_in_if<bool> >*>( pb ); if( in_port != 0 ) { rand->edgy_sig = DCAST<const sc_signal_in_if<bool>*>( in_port->get_interface() ); assert( rand->edgy_sig != 0 ); break; } const sc_port_b<sc_signal_inout_if<bool> >* inout_port = DCAST<const sc_port_b<sc_signal_inout_if<bool> >*>( pb ); if( inout_port != 0 ) { rand->edgy_sig = DCAST<const sc_signal_in_if<bool>*>( inout_port->get_interface() ); assert( rand->edgy_sig != 0 ); break; } // this should not happen assert( false ); break; } case SC_LAMBDA_RAND_SIGNAL_SUL: { // the tricky part, reversed const sc_port_base* pb = RCAST<const sc_port_base*>( rand->sul_sig ); // check if pb is a port bool is_port = false; for( int i = registry->size() - 1; i >= 0; -- i ) { if( pb == registry->m_port_vec[i] ) { is_port = true; break; } } if( ! is_port ) { break; } // cast pb to the appropriate port type const sc_port_b<sc_signal_in_if<sc_logic> >* in_port = DCAST<const sc_port_b<sc_signal_in_if<sc_logic> >*>( pb ); if( in_port != 0 ) { rand->sul_sig = DCAST<const sc_signal_in_if<sc_logic>*>( in_port->get_interface() ); assert( rand->sul_sig != 0 ); break; } const sc_port_b<sc_signal_inout_if<sc_logic> >* inout_port = DCAST<const sc_port_b<sc_signal_inout_if<sc_logic> >*>( pb ); if( inout_port != 0 ) { rand->sul_sig = DCAST<const sc_signal_in_if<sc_logic>*>( inout_port->get_interface() ); assert( rand->sul_sig != 0 ); break; } // this should not happen assert( false ); break; } default: break; }}// Taf!
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?