sc_simcontext.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 925 行 · 第 1/2 页
CPP
925 行
/***************************************************************************** The following code is derived, directly or indirectly, from the SystemC source code Copyright (c) 1996-2002 by all Contributors. All Rights reserved. The contents of this file are subject to the restrictions and limitations set forth in the SystemC Open Source License Version 2.3 (the "License"); You may not use this file except in compliance with such restrictions and limitations. You may obtain instructions on how to receive a copy of the License at http://www.systemc.org/. Software distributed by Contributors under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. *****************************************************************************//***************************************************************************** sc_simcontext.cpp -- Provides a simulation context for use with multiple simulations. Original Author: Stan Y. Liao, Synopsys, Inc. Martin Janssen, Synopsys, Inc. *****************************************************************************//***************************************************************************** MODIFICATION LOG - modifiers, enter your name, affiliation, date and changes you are making here. Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. Description of Modification: - Added sc_stop() detection into initial_crunch and crunch. This makes it possible to exit out of a combinational loop using sc_stop(). Name, Affiliation, Date: Description of Modification: *****************************************************************************/#include "systemc/kernel/sc_cor_fiber.h"#include "systemc/kernel/sc_cor_qt.h"#include "systemc/kernel/sc_event.h"#include "systemc/kernel/sc_kernel_ids.h"#include "systemc/kernel/sc_lambda.h"#include "systemc/kernel/sc_macros_int.h"#include "systemc/kernel/sc_module.h"#include "systemc/kernel/sc_module_registry.h"#include "systemc/kernel/sc_name_gen.h"#include "systemc/kernel/sc_object_manager.h"#include "systemc/kernel/sc_process_int.h"#include "systemc/kernel/sc_simcontext.h"#include "systemc/kernel/sc_simcontext_int.h"#include "systemc/kernel/sc_ver.h"#include "systemc/communication/sc_port.h"#include "systemc/communication/sc_prim_channel.h"#include "systemc/tracing/sc_trace.h"#include "systemc/utils/sc_exception.h"#include "systemc/utils/sc_mempool.h"// ----------------------------------------------------------------------------// CLASS : sc_process_table//// Container class that keeps track of all method processes,// thread processes, and cthread processes.// ----------------------------------------------------------------------------typedef sc_pvector<sc_method_handle> sc_method_vec;typedef sc_pvector<sc_thread_handle> sc_thread_vec;typedef sc_pvector<sc_cthread_handle> sc_cthread_vec;class sc_process_table{public: sc_process_table(); ~sc_process_table(); void push_back( sc_method_handle ); void push_back( sc_thread_handle ); void push_back( sc_cthread_handle ); sc_method_handle remove( sc_method_handle ); sc_thread_handle remove( sc_thread_handle ); sc_cthread_handle remove( sc_cthread_handle ); int num_methods() const; int num_threads() const; int num_cthreads() const; const sc_method_vec& method_vec() const; const sc_thread_vec& thread_vec() const; const sc_cthread_vec& cthread_vec() const;private: sc_method_vec m_method_vec; sc_thread_vec m_thread_vec; sc_cthread_vec m_cthread_vec;};// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIsc_process_table::sc_process_table(){}sc_process_table::~sc_process_table(){ // delete all method processes for( int i = m_method_vec.size() - 1; i >= 0; -- i ) { delete m_method_vec[i]; } // delete all thread processes for( int i = m_thread_vec.size() - 1; i >= 0; -- i ) { delete m_thread_vec[i]; } // delete all cthread processes for( int i = m_cthread_vec.size() - 1; i >= 0; -- i ) { delete m_cthread_vec[i]; }}inlinevoidsc_process_table::push_back( sc_method_handle handle_ ){ m_method_vec.push_back( handle_ );}inlinevoidsc_process_table::push_back( sc_thread_handle handle_ ){ m_thread_vec.push_back( handle_ );}inlinevoidsc_process_table::push_back( sc_cthread_handle handle_ ){ m_cthread_vec.push_back( handle_ );}sc_method_handlesc_process_table::remove( sc_method_handle handle_ ){ int size = m_method_vec.size(); for( int i = 0; i < size; ++ i ) { if( m_method_vec[i] == handle_ ) { m_method_vec[i] = m_method_vec[size - 1]; m_method_vec.decr_count(); return handle_; } } return 0;}sc_thread_handlesc_process_table::remove( sc_thread_handle handle_ ){ int size = m_thread_vec.size(); for( int i = 0; i < size; ++ i ) { if( m_thread_vec[i] == handle_ ) { m_thread_vec[i] = m_thread_vec[size - 1]; m_thread_vec.decr_count(); return handle_; } } return 0;}sc_cthread_handlesc_process_table::remove( sc_cthread_handle handle_ ){ int size = m_cthread_vec.size(); for( int i = 0; i < size; ++ i ) { if( m_cthread_vec[i] == handle_ ) { m_cthread_vec[i] = m_cthread_vec[size - 1]; m_cthread_vec.decr_count(); return handle_; } } return 0;}inlineintsc_process_table::num_methods() const{ return m_method_vec.size();}inlineintsc_process_table::num_threads() const{ return m_thread_vec.size();}inlineintsc_process_table::num_cthreads() const{ return m_cthread_vec.size();}inlineconst sc_method_vec&sc_process_table::method_vec() const{ return m_method_vec;}inlineconst sc_thread_vec&sc_process_table::thread_vec() const{ return m_thread_vec;}inlineconst sc_cthread_vec&sc_process_table::cthread_vec() const{ return m_cthread_vec;}// ----------------------------------------------------------------------------voidpln(){ static bool lnp = false; if( ! lnp ) { cerr << endl; cerr << sc_version() << endl; cerr << sc_copyright() << endl; // regressions check point if( getenv( "SYSTEMC_REGRESSION" ) != 0 ) { cerr << "SystemC Simulation" << endl; } lnp = true; }}intsc_notify_time_compare( const void* p1, const void* p2 ){ const sc_event_timed* et1 = static_cast<const sc_event_timed*>( p1 ); const sc_event_timed* et2 = static_cast<const sc_event_timed*>( p2 ); const sc_time& t1 = et1->notify_time(); const sc_time& t2 = et2->notify_time(); if( t1 < t2 ) { return 1; } else if( t1 > t2 ) { return -1; } else { return 0; }}// ----------------------------------------------------------------------------// CLASS : sc_simcontext//// The simulation context.// ----------------------------------------------------------------------------voidsc_simcontext::init(){ m_object_manager = new sc_object_manager; m_module_registry = new sc_module_registry( *this ); m_port_registry = new sc_port_registry( *this ); m_prim_channel_registry = new sc_prim_channel_registry( *this ); m_name_gen = new sc_name_gen; m_process_table = new sc_process_table; reset_curr_proc(); m_next_proc_id = -1; m_timed_events = new sc_ppq<sc_event_timed*>( 128, sc_notify_time_compare ); m_something_to_trace = false; m_runnable = new sc_runnable; m_time_params = new sc_time_params; m_curr_time = SC_ZERO_TIME; m_delta_count = 0; m_forced_stop = false; m_ready_to_simulate = false; m_update_phase = false; m_error = false; m_until_event = 0; m_cor_pkg = 0; m_cor = 0; m_watching_fn = watching_before_simulation;}voidsc_simcontext::clean(){ delete m_object_manager; delete m_module_registry; delete m_port_registry; delete m_prim_channel_registry; delete m_name_gen; delete m_process_table; m_child_objects.erase_all(); m_delta_events.erase_all(); delete m_timed_events; for( int i = m_trace_files.size() - 1; i >= 0; -- i ) { delete m_trace_files[i]; } m_trace_files.erase_all(); delete m_runnable; delete m_time_params; if( m_until_event != 0 ) { delete m_until_event; } if( m_cor_pkg != 0 ) { delete m_cor_pkg; }}sc_simcontext::sc_simcontext(){ init();}sc_simcontext::~sc_simcontext(){ clean();}voidsc_simcontext::initialize( bool no_crunch ){ if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) { return; } m_port_registry->elaboration_done(); m_prim_channel_registry->elaboration_done(); m_module_registry->elaboration_done(); // check for call(s) to sc_stop if( m_forced_stop ) { cout << "SystemC: simulation stopped by user." << endl; return; } m_watching_fn = watching_during_simulation; // allocate space in the runnable queues m_runnable->alloc( m_process_table->num_methods(), m_process_table->num_threads() + m_process_table->num_cthreads() ); // instantiate the coroutine package#ifndef WIN32 m_cor_pkg = new sc_cor_pkg_qt( this );#else m_cor_pkg = new sc_cor_pkg_fiber( this );#endif m_cor = m_cor_pkg->get_main(); // prepare all thread processes for simulation const sc_thread_vec& thread_vec = m_process_table->thread_vec(); for( int i = thread_vec.size() - 1; i >= 0; -- i ) { thread_vec[i]->prepare_for_simulation(); } // prepare all cthread processes for simulation const sc_cthread_vec& cthread_vec = m_process_table->cthread_vec(); for( int i = cthread_vec.size() - 1; i >= 0; -- i ) { cthread_vec[i]->prepare_for_simulation(); } m_ready_to_simulate = true; m_runnable->init(); // update phase m_update_phase = true; m_prim_channel_registry->perform_update(); m_update_phase = false; int size; // make all method processes runnable const sc_method_vec& method_vec = m_process_table->method_vec(); size = method_vec.size(); for( int i = 0; i < size; ++ i ) { sc_method_handle method_h = method_vec[i]; if( method_h->do_initialize() ) { push_runnable_method( method_h ); } } // make all thread processes runnable size = thread_vec.size(); for( int i = 0; i < size; ++ i ) { sc_thread_handle thread_h = thread_vec[i]; if( thread_h->do_initialize() ) { push_runnable_thread( thread_h ); } } // process delta notifications if( ( size = m_delta_events.size() ) != 0 ) { sc_event** l_delta_events = m_delta_events.raw_data(); int i = size - 1; do { l_delta_events[i]->trigger(); } while( -- i >= 0 ); m_delta_events.erase_all(); } // used in 'simulate()' m_until_event = new sc_event; if( no_crunch || m_runnable->push_empty() ) { return; } m_runnable->toggle(); // run the delta cycle loop 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; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?