sc_simcontext.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2006 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_simcontext.cpp -- Provides a simulation context for use with multiple
00021                        simulations.
00022 
00023   Original Author: Stan Y. Liao, Synopsys, Inc.
00024                    Martin Janssen, Synopsys, Inc.
00025 
00026  *****************************************************************************/
00027 
00028 /*****************************************************************************
00029 
00030   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00031   changes you are making here.
00032 
00033       Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
00034   Description of Modification: - Added sc_stop() detection into initial_crunch
00035                                  and crunch. This makes it possible to exit out
00036                                  of a combinational loop using sc_stop().
00037 
00038       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
00039   Description of Modification: - sc_stop mode
00040                                - phase callbacks
00041 
00042       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00043                                25 August 2003
00044   Description of Modification: - support for dynamic process
00045                                - support for sc export registry
00046                                - new member methods elaborate(), 
00047                  prepare_to_simulate(), and initial_crunch()
00048                  that are invoked by initialize() in that order
00049                                - implement sc_get_last_created_process_handle() for use
00050                                  before simulation starts
00051                                - remove "set_curr_proc(handle)" from 
00052                                  register_method_process and 
00053                                  register_thread_process - led to bugs
00054                                
00055       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 04 Sep 2003
00056   Description of Modification: - changed process existence structures to
00057                  linked lists to eliminate exponential 
00058                  execution problem with using sc_pvector.
00059  *****************************************************************************/
00060 // $Log: sc_simcontext.cpp,v $
00061 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00062 // SystemC 2.2
00063 //
00064 // Revision 1.17  2006/04/11 23:13:21  acg
00065 //   Andy Goodrich: Changes for reduced reset support that only includes
00066 //   sc_cthread, but has preliminary hooks for expanding to method and thread
00067 //   processes also.
00068 //
00069 // Revision 1.16  2006/03/21 00:00:34  acg
00070 //   Andy Goodrich: changed name of sc_get_current_process_base() to be
00071 //   sc_get_current_process_b() since its returning an sc_process_b instance.
00072 //
00073 // Revision 1.15  2006/03/13 20:26:50  acg
00074 //  Andy Goodrich: Addition of forward class declarations, e.g.,
00075 //  sc_reset, to keep gcc 4.x happy.
00076 //
00077 // Revision 1.14  2006/02/02 23:42:41  acg
00078 //  Andy Goodrich: implemented a much better fix to the sc_event_finder
00079 //  proliferation problem. This new version allocates only a single event
00080 //  finder for each port for each type of event, e.g., pos(), neg(), and
00081 //  value_change(). The event finder persists as long as the port does,
00082 //  which is what the LRM dictates. Because only a single instance is
00083 //  allocated for each event type per port there is not a potential
00084 //  explosion of storage as was true in the 2.0.1/2.1 versions.
00085 //
00086 // Revision 1.13  2006/02/02 21:29:10  acg
00087 //  Andy Goodrich: removed the call to sc_event_finder::free_instances() that
00088 //  was in end_of_elaboration(), leaving only the call in clean(). This is
00089 //  because the LRM states that sc_event_finder instances are persistent as
00090 //  long as the sc_module hierarchy is valid.
00091 //
00092 // Revision 1.12  2006/02/02 21:09:50  acg
00093 //  Andy Goodrich: added call to sc_event_finder::free_instances in the clean()
00094 //  method.
00095 //
00096 // Revision 1.11  2006/02/02 20:43:14  acg
00097 //  Andy Goodrich: Added an existence linked list to sc_event_finder so that
00098 //  the dynamically allocated instances can be freed after port binding
00099 //  completes. This replaces the individual deletions in ~sc_bind_ef, as these
00100 //  caused an exception if an sc_event_finder instance was used more than
00101 //  once, due to a double freeing of the instance.
00102 //
00103 // Revision 1.10  2006/01/31 21:43:26  acg
00104 //  Andy Goodrich: added comments in constructor to highlight environmental
00105 //  overrides section.
00106 //
00107 // Revision 1.9  2006/01/26 21:04:54  acg
00108 //  Andy Goodrich: deprecation message changes and additional messages.
00109 //
00110 // Revision 1.8  2006/01/25 00:31:19  acg
00111 //  Andy Goodrich: Changed over to use a standard message id of
00112 //  SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
00113 //
00114 // Revision 1.7  2006/01/24 20:49:05  acg
00115 // Andy Goodrich: changes to remove the use of deprecated features within the
00116 // simulator, and to issue warning messages when deprecated features are used.
00117 //
00118 // Revision 1.6  2006/01/19 00:29:52  acg
00119 // Andy Goodrich: Yet another implementation for signal write checking. This
00120 // one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
00121 // DISABLE will disable write checking on signals.
00122 //
00123 // Revision 1.5  2006/01/13 18:44:30  acg
00124 // Added $Log to record CVS changes into the source.
00125 //
00126 // Revision 1.4  2006/01/03 23:18:44  acg
00127 // Changed copyright to include 2006.
00128 //
00129 // Revision 1.3  2005/12/20 22:11:10  acg
00130 // Fixed $Log lines.
00131 //
00132 // Revision 1.2  2005/12/20 22:02:30  acg
00133 // Changed where delta cycles are incremented to match IEEE 1666. Added the
00134 // event_occurred() method to hide how delta cycle comparisions are done within
00135 // sc_simcontext. Changed the boolean update_phase to an enum that shows all
00136 // the phases.
00137 
00138 #include "sysc/kernel/sc_cor_fiber.h"
00139 #include "sysc/kernel/sc_cor_pthread.h"
00140 #include "sysc/kernel/sc_cor_qt.h"
00141 #include "sysc/kernel/sc_event.h"
00142 #include "sysc/kernel/sc_kernel_ids.h"
00143 #include "sysc/kernel/sc_macros_int.h"
00144 #include "sysc/kernel/sc_module.h"
00145 #include "sysc/kernel/sc_module_registry.h"
00146 #include "sysc/kernel/sc_name_gen.h"
00147 #include "sysc/kernel/sc_object_manager.h"
00148 #include "sysc/kernel/sc_cthread_process.h"
00149 #include "sysc/kernel/sc_method_process.h"
00150 #include "sysc/kernel/sc_thread_process.h"
00151 #include "sysc/kernel/sc_process_handle.h"
00152 #include "sysc/kernel/sc_simcontext.h"
00153 #include "sysc/kernel/sc_simcontext_int.h"
00154 #include "sysc/kernel/sc_reset.h"
00155 #include "sysc/kernel/sc_ver.h"
00156 #include "sysc/communication/sc_port.h"
00157 #include "sysc/communication/sc_export.h"
00158 #include "sysc/communication/sc_prim_channel.h"
00159 #include "sysc/tracing/sc_trace.h"
00160 #include "sysc/utils/sc_mempool.h"
00161 #include "sysc/utils/sc_utils_ids.h"
00162 
00163 namespace sc_core {
00164 
00165 sc_stop_mode stop_mode = SC_STOP_FINISH_DELTA;
00166 
00167 // ----------------------------------------------------------------------------
00168 //  CLASS : sc_process_table
00169 //
00170 //  Container class that keeps track of all method processes,
00171 //  thread processes, and cthread processes.
00172 // ----------------------------------------------------------------------------
00173 
00174 class sc_process_table
00175 {
00176   public:
00177 
00178     sc_process_table();
00179     ~sc_process_table();
00180     void push_front( sc_method_handle );
00181     void push_front( sc_thread_handle );
00182     void push_front( sc_cthread_handle );
00183     sc_cthread_handle cthread_q_head();
00184     sc_method_handle method_q_head();
00185     sc_cthread_handle remove( sc_cthread_handle );
00186     sc_method_handle remove( sc_method_handle );
00187     sc_thread_handle remove( sc_thread_handle );
00188     sc_thread_handle thread_q_head();
00189 
00190 
00191   private:
00192 
00193     sc_cthread_handle m_cthread_q; // Queue of existing cthread processes.
00194     sc_method_handle  m_method_q;  // Queue of existing method processes.
00195     sc_thread_handle  m_thread_q;  // Queue of existing thread processes.
00196 };
00197 
00198 
00199 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00200 
00201 sc_process_table::sc_process_table() :
00202     m_cthread_q(0), m_method_q(0), m_thread_q(0)
00203 {}
00204 
00205 sc_process_table::~sc_process_table()
00206 {
00207 
00208     sc_method_handle  method_next_p;    // Next method to delete.
00209     sc_method_handle  method_now_p; // Method now deleting.
00210 
00211     for( method_now_p = m_method_q; method_now_p; method_now_p = method_next_p )
00212     {
00213     method_next_p = method_now_p->next_exist();
00214     delete method_now_p;
00215     }
00216 
00217     if ( m_thread_q || m_cthread_q )
00218     {
00219         ::std::cout << ::std::endl 
00220              << "WATCH OUT!! In sc_process_table destructor. "
00221              << "Threads and cthreads are not actually getting deleted here. "
00222          << "Some memory may leak. Look at the comments here in "
00223          << "kernel/sc_simcontext.cpp for more details."
00224          << ::std::endl;
00225     }
00226 
00227     // don't delete threads and cthreads. If a (c)thread
00228     // has died, then it has already been deleted. Only (c)threads created
00229     // before simulation-start are in this table. Due to performance
00230     // reasons, we don't look up the dying thread in the process table
00231     // and remove it from there. simcontext::reset and ~simcontext invoke this
00232     // destructor. At present none of these routines are ever invoked. 
00233     // We can delete threads and cthreads here if a dying thread figured out
00234     // it was created before simulation-start and took itself off the 
00235     // process_table. 
00236 
00237 #if 0
00238     sc_cthread_handle cthread_next_p;   // Next cthread to delete.
00239     sc_cthread_handle cthread_now_p;    // Cthread now deleting.
00240     sc_thread_handle  thread_next_p;    // Next thread to delete.
00241     sc_thread_handle  thread_now_p; // Thread now deleting.
00242 
00243     for(cthread_now_p=m_cthread_q; cthread_now_p; cthread_now_p=cthread_next_p)
00244     {
00245     cthread_next_p = cthread_now_p->next_exist();
00246     delete cthread_now_p;
00247     }
00248 
00249     for( thread_now_p=m_thread_q; thread_now_p; thread_now_p=thread_next_p )
00250     {
00251     thread_next_p = thread_now_p->next_exist();
00252     delete thread_now_p;
00253     }
00254 #endif // 0
00255 }
00256 
00257 inline
00258 sc_cthread_handle 
00259 sc_process_table::cthread_q_head()
00260 {
00261     return m_cthread_q;
00262 }
00263 
00264 inline
00265 sc_method_handle 
00266 sc_process_table::method_q_head()
00267 {
00268     return m_method_q;
00269 }
00270 
00271 inline
00272 void
00273 sc_process_table::push_front( sc_method_handle handle_ )
00274 {
00275     handle_->set_next_exist(m_method_q);
00276     m_method_q = handle_;
00277 }
00278 
00279 inline
00280 void
00281 sc_process_table::push_front( sc_thread_handle handle_ )
00282 {
00283     handle_->set_next_exist(m_thread_q);
00284     m_thread_q = handle_;
00285 }
00286 
00287 inline
00288 void
00289 sc_process_table::push_front( sc_cthread_handle handle_ )
00290 {
00291     handle_->set_next_exist(m_cthread_q);
00292     m_cthread_q = handle_;
00293 }
00294 
00295 
00296 sc_cthread_handle
00297 sc_process_table::remove( sc_cthread_handle handle_ )
00298 {
00299     sc_cthread_handle now_p;    // Entry now examining.
00300     sc_cthread_handle prior_p;  // Entry prior to one now examining.
00301 
00302     prior_p = 0;
00303     for ( now_p = m_cthread_q; now_p; now_p = now_p->next_exist() )
00304     {
00305     if ( now_p == handle_ )
00306     {
00307         if ( prior_p )
00308         prior_p->set_next_exist( now_p->next_exist() );
00309         else
00310         m_cthread_q = now_p->next_exist();
00311         return handle_;
00312     }
00313     }
00314     return 0;
00315 }
00316 
00317 sc_method_handle
00318 sc_process_table::remove( sc_method_handle handle_ )
00319 {
00320     sc_method_handle now_p; // Entry now examining.
00321     sc_method_handle prior_p;   // Entry prior to one now examining.
00322 
00323     prior_p = 0;
00324     for ( now_p = m_method_q; now_p; now_p = now_p->next_exist() )
00325     {
00326     if ( now_p == handle_ )
00327     {
00328         if ( prior_p )
00329         prior_p->set_next_exist( now_p->next_exist() );
00330         else
00331         m_method_q = now_p->next_exist();
00332         return handle_;
00333     }
00334     }
00335     return 0;
00336 }
00337 
00338 sc_thread_handle
00339 sc_process_table::remove( sc_thread_handle handle_ )
00340 {
00341     sc_thread_handle now_p; // Entry now examining.
00342     sc_thread_handle prior_p;   // Entry prior to one now examining.
00343 
00344     prior_p = 0;
00345     for ( now_p = m_thread_q; now_p; now_p = now_p->next_exist() )
00346     {
00347     if ( now_p == handle_ )
00348     {
00349         if ( prior_p )
00350         prior_p->set_next_exist( now_p->next_exist() );
00351         else
00352         m_thread_q = now_p->next_exist();
00353         return handle_;
00354     }
00355     }
00356     return 0;
00357 }
00358 
00359 inline
00360 sc_thread_handle 
00361 sc_process_table::thread_q_head()
00362 {
00363     return m_thread_q;
00364 }
00365 
00366 
00367 
00368 // ----------------------------------------------------------------------------
00369 
00370 void
00371 pln()
00372 {
00373     static bool lnp = false;
00374     if( ! lnp ) {
00375         ::std::cerr << ::std::endl;
00376     ::std::cerr << sc_version() << ::std::endl;
00377     ::std::cerr << sc_copyright() << ::std::endl;
00378 
00379     //  regressions check point
00380         if( getenv( "SYSTEMC_REGRESSION" ) != 0 ) {
00381             ::std::cerr << "SystemC Simulation" << ::std::endl;
00382         }
00383 
00384         lnp = true;
00385     }
00386 }
00387 
00388 
00389 int
00390 sc_notify_time_compare( const void* p1, const void* p2 )
00391 {
00392     const sc_event_timed* et1 = static_cast<const sc_event_timed*>( p1 );
00393     const sc_event_timed* et2 = static_cast<const sc_event_timed*>( p2 );
00394 
00395     const sc_time& t1 = et1->notify_time();
00396     const sc_time& t2 = et2->notify_time();
00397     
00398     if( t1 < t2 ) {
00399     return 1;
00400     } else if( t1 > t2 ) {
00401     return -1;
00402     } else {
00403     return 0;
00404     }
00405 }
00406 
00407 
00408 // ----------------------------------------------------------------------------
00409 //  CLASS : sc_simcontext
00410 //
00411 //  The simulation context.
00412 // ----------------------------------------------------------------------------
00413 
00414 void
00415 sc_simcontext::init()
00416 {
00417 
00418     // ALLOCATE VARIOUS MANAGERS AND REGISTRIES:
00419 
00420     m_object_manager = new sc_object_manager;
00421     m_module_registry = new sc_module_registry( *this );
00422     m_port_registry = new sc_port_registry( *this );
00423     m_export_registry = new sc_export_registry( *this );
00424     m_prim_channel_registry = new sc_prim_channel_registry( *this );
00425     m_name_gen = new sc_name_gen;
00426     m_process_table = new sc_process_table;
00427     m_current_writer = 0;
00428 
00429 
00430     // CHECK FOR ENVIRONMENT VARIABLES THAT MODIFY SIMULATOR EXECUTION:
00431 
00432     const char* write_check = std::getenv("SC_SIGNAL_WRITE_CHECK");
00433     m_write_check = ( (write_check==0) || strcmp(write_check,"DISABLE") ) ?
00434       true : false;
00435 
00436 
00437     // FINISH INITIALIZATIONS:
00438 
00439     reset_curr_proc();
00440     m_next_proc_id = -1;
00441     m_timed_events = new sc_ppq<sc_event_timed*>( 128, sc_notify_time_compare );
00442     m_something_to_trace = false;
00443     m_runnable = new sc_runnable;
00444     m_time_params = new sc_time_params;
00445     m_curr_time = SC_ZERO_TIME;
00446     m_delta_count = 0;
00447     m_forced_stop = false;
00448     m_ready_to_simulate = false;
00449     m_elaboration_done = false;
00450     m_execution_phase = phase_initialize;
00451     m_error = false;
00452     m_until_event = 0;
00453     m_cor_pkg = 0;
00454     m_cor = 0;
00455     m_in_simulator_control = false;
00456     m_start_of_simulation_called = false;
00457     m_end_of_simulation_called = false;
00458 }
00459 
00460 void
00461 sc_simcontext::clean()
00462 {
00463     delete m_object_manager;
00464     delete m_module_registry;
00465     delete m_port_registry;
00466     delete m_export_registry;
00467     delete m_prim_channel_registry;
00468     delete m_name_gen;
00469     delete m_process_table;
00470     m_child_objects.resize(0);
00471     m_delta_events.resize(0);
00472     delete m_timed_events;
00473     for( int i = m_trace_files.size() - 1; i >= 0; -- i ) {
00474     delete m_trace_files[i];
00475     }
00476     m_trace_files.resize(0);
00477     delete m_runnable;
00478     delete m_time_params;
00479     if( m_until_event != 0 ) {
00480         delete m_until_event;
00481     }
00482     if( m_cor_pkg != 0 ) {
00483     delete m_cor_pkg;
00484     }
00485 }
00486 
00487 
00488 sc_simcontext::sc_simcontext()
00489 {
00490     init();
00491 }
00492 
00493 sc_simcontext::~sc_simcontext()
00494 {
00495     clean();
00496 }
00497 
00498 inline void
00499 sc_simcontext::crunch( bool once )
00500 {
00501 #ifdef DEBUG_SYSTEMC
00502     int num_deltas = 0;  // number of delta cycles
00503 #endif
00504 
00505     while ( true ) {
00506 
00507     // EVALUATE PHASE
00508     
00509     m_execution_phase = phase_evaluate;
00510     while( true ) {
00511 
00512 
00513         // execute method processes
00514 
00515         sc_method_handle method_h = pop_runnable_method();
00516         while( method_h != 0 ) {
00517         try {
00518             method_h->semantics();
00519         }
00520         catch( const sc_report& ex ) {
00521             ::std::cout << "\n" << ex.what() << ::std::endl;
00522             m_error = true;
00523             return;
00524         }
00525         method_h = pop_runnable_method();
00526         }
00527 
00528         // execute (c)thread processes
00529 
00530         sc_thread_handle thread_h = pop_runnable_thread();
00531         while( thread_h != 0 ) {
00532         if ( thread_h->ready_to_run() ) break;
00533         thread_h = pop_runnable_thread();
00534         }
00535         if( thread_h != 0 ) {
00536         m_cor_pkg->yield( thread_h->m_cor_p );
00537         }
00538         if( m_error ) {
00539         return;
00540         }
00541 
00542         // check for call(s) to sc_stop
00543         if( m_forced_stop ) {
00544         if ( stop_mode == SC_STOP_IMMEDIATE ) return;
00545         }
00546 
00547         if( m_runnable->is_empty() ) {
00548         // no more runnable processes
00549         break;
00550         }
00551         m_runnable->toggle();
00552     }
00553 
00554     // UPDATE PHASE
00555     //
00556     // The delta count must be updated first so that event_occurred()
00557     // will work.
00558 
00559     m_execution_phase = phase_update;
00560     m_delta_count ++;
00561     m_prim_channel_registry->perform_update();
00562     m_execution_phase = phase_notify;
00563     
00564     if( m_something_to_trace ) {
00565         trace_cycle( /* delta cycle? */ true );
00566     }
00567 
00568     // m_delta_count ++;
00569 
00570         // check for call(s) to sc_stop
00571         if( m_forced_stop ) {
00572             break;
00573         }
00574 
00575 #ifdef DEBUG_SYSTEMC
00576         // check for possible infinite loops
00577         if( ++ num_deltas > SC_MAX_NUM_DELTA_CYCLES ) {
00578         ::std::cerr << "SystemC warning: "
00579          << "the number of delta cycles exceeds the limit of "
00580          << SC_MAX_NUM_DELTA_CYCLES
00581          << ", defined in sc_constants.h.\n"
00582          << "This is a possible sign of an infinite loop.\n"
00583          << "Increase the limit if this warning is invalid.\n";
00584         break;
00585     }
00586 #endif
00587 
00588     // PROCESS DELTA NOTIFICATIONS:
00589 
00590         int size = m_delta_events.size();
00591     if ( size != 0 )
00592     {
00593         sc_event** l_events = &m_delta_events[0];
00594         int i = size - 1;
00595         do {
00596         l_events[i]->trigger();
00597         } while( -- i >= 0 );
00598         m_delta_events.resize(0);
00599     }
00600     
00601     if( m_runnable->is_empty() ) {
00602         // no more runnable processes
00603         break;
00604     }
00605 
00606     // IF ONLY DOING ONE CYCLE, WE ARE DONE. OTHERWISE GET NEW CALLBACKS
00607 
00608     if ( once ) break;
00609 
00610     m_runnable->toggle();
00611     } 
00612 }
00613 
00614 inline
00615 void
00616 sc_simcontext::cycle( const sc_time& t)
00617 {
00618     sc_time next_event_time;
00619 
00620     m_in_simulator_control = true;
00621     m_runnable->toggle();
00622     crunch(); 
00623     trace_cycle( /* delta cycle? */ false );
00624     m_curr_time += t;
00625     next_event_time = next_time();
00626     if ( next_event_time != SC_ZERO_TIME && next_event_time <= m_curr_time) {
00627         SC_REPORT_WARNING(SC_ID_CYCLE_MISSES_EVENTS_, "");
00628     }
00629     m_in_simulator_control = false;
00630 }
00631 
00632 void
00633 sc_simcontext::elaborate()
00634 {
00635     if( m_elaboration_done || sim_status() != SC_SIM_OK ) {
00636         return;
00637     }
00638 
00639     m_port_registry->construction_done();
00640     m_export_registry->construction_done();
00641     m_prim_channel_registry->construction_done();
00642     m_module_registry->construction_done();
00643 
00644     // check for call(s) to sc_stop
00645     if( m_forced_stop ) {
00646         do_sc_stop_action();
00647         return;
00648     }
00649 
00650     // SIGNAL THAT ELABORATION IS DONE
00651     //
00652     // We set the switch before the calls in case someone creates a process 
00653     // in an end_of_elaboration callback. We need the information to flag 
00654     // the process as being dynamic.
00655 
00656     m_elaboration_done = true;
00657 
00658     m_port_registry->elaboration_done();
00659     m_export_registry->elaboration_done();
00660     m_prim_channel_registry->elaboration_done();
00661     m_module_registry->elaboration_done();
00662     sc_reset::reconcile_resets();
00663 
00664     // check for call(s) to sc_stop
00665     if( m_forced_stop ) {
00666         do_sc_stop_action();
00667         return;
00668     }
00669 }
00670 
00671 void
00672 sc_simcontext::prepare_to_simulate()
00673 {
00674     sc_cthread_handle cthread_p; // Pointer to cthread process accessing.
00675     sc_method_handle  method_p;  // Pointer to method process accessing.
00676     sc_thread_handle  thread_p;  // Pointer to thread process accessing.
00677 
00678     if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) {
00679         return;
00680     }
00681 
00682     // instantiate the coroutine package
00683 #   if defined(WIN32)
00684         m_cor_pkg = new sc_cor_pkg_fiber( this );
00685 #   else
00686 #       if defined(SC_USE_PTHREADS)
00687             m_cor_pkg = new sc_cor_pkg_pthread( this );
00688 #       else
00689             m_cor_pkg = new sc_cor_pkg_qt( this );
00690 #       endif
00691 #   endif
00692     m_cor = m_cor_pkg->get_main();
00693 
00694     // NOTIFY ALL OBJECTS THAT SIMULATION IS ABOUT TO START:
00695 
00696     m_port_registry->start_simulation();
00697     m_export_registry->start_simulation();
00698     m_prim_channel_registry->start_simulation();
00699     m_module_registry->start_simulation();
00700     m_start_of_simulation_called = true;
00701 
00702     // CHECK FOR CALL(S) TO sc_stop 
00703 
00704     if( m_forced_stop ) {
00705         do_sc_stop_action();
00706         return;
00707     }
00708 
00709     // PREPARE ALL (C)THREAD PROCESSES FOR SIMULATION:
00710 
00711     for ( thread_p = m_process_table->thread_q_head(); 
00712       thread_p; thread_p = thread_p->next_exist() )
00713     {
00714     thread_p->prepare_for_simulation();
00715     }
00716 
00717     for ( cthread_p = m_process_table->cthread_q_head(); 
00718       cthread_p; cthread_p = cthread_p->next_exist() )
00719     {
00720     cthread_p->prepare_for_simulation();
00721     }
00722 
00723     m_ready_to_simulate = true;
00724     m_runnable->init();
00725 
00726     // update phase
00727 
00728     m_execution_phase = phase_update;
00729     m_prim_channel_registry->perform_update();
00730     m_execution_phase = phase_notify;
00731 
00732     int size;
00733 
00734     // make all method processes runnable
00735 
00736     for ( method_p = m_process_table->method_q_head(); 
00737       method_p; method_p = method_p->next_exist() )
00738     {
00739         if( !method_p->dont_initialize() ) {
00740             push_runnable_method_front( method_p );
00741         }
00742     }
00743 
00744     // make all thread processes runnable
00745 
00746     for ( thread_p = m_process_table->thread_q_head(); 
00747       thread_p; thread_p = thread_p->next_exist() )
00748     {
00749         if( !thread_p->dont_initialize() ) {
00750             push_runnable_thread_front( thread_p );
00751         }
00752     }
00753 
00754 
00755     // process delta notifications
00756 
00757     if( ( size = m_delta_events.size() ) != 0 ) {
00758         sc_event** l_delta_events = &m_delta_events[0];
00759         int i = size - 1;
00760         do {
00761             l_delta_events[i]->trigger();
00762         } while( -- i >= 0 );
00763         m_delta_events.resize(0);
00764     }
00765 
00766     // used in 'simulate()'
00767     m_until_event = new sc_event;
00768 
00769     if( m_runnable->is_empty() ) {
00770         m_delta_count++;
00771     }
00772 }
00773 
00774 void
00775 sc_simcontext::initial_crunch( bool no_crunch )
00776 {
00777     if( no_crunch || m_runnable->is_empty() ) {
00778         return;
00779     }
00780     m_runnable->toggle();
00781 
00782     // run the delta cycle loop
00783 
00784     crunch();
00785     if( m_error ) {
00786         return;
00787     }
00788     if( m_something_to_trace ) {
00789         trace_cycle( false );
00790     }
00791     // check for call(s) to sc_stop
00792     if( m_forced_stop ) {
00793         do_sc_stop_action();
00794     }
00795 }
00796 
00797 void
00798 sc_simcontext::initialize( bool no_crunch )
00799 {
00800     m_in_simulator_control = true;
00801     elaborate();
00802     prepare_to_simulate();
00803     initial_crunch(no_crunch);
00804     m_in_simulator_control = false;
00805 }
00806 
00807 void
00808 sc_simcontext::simulate( const sc_time& duration )
00809 {
00810     initialize( true );
00811 
00812     if (sim_status() != SC_SIM_OK) {
00813     return;
00814     }
00815 
00816     sc_time non_overflow_time = 
00817         sc_time(~sc_dt::UINT64_ZERO, false) - m_curr_time;
00818     if ( duration > non_overflow_time )
00819     {
00820     SC_REPORT_ERROR(SC_ID_SIMULATION_TIME_OVERFLOW_, "");
00821     return;
00822     }
00823     else if ( duration < SC_ZERO_TIME )
00824     {
00825     SC_REPORT_ERROR(SC_ID_NEGATIVE_SIMULATION_TIME_,"");
00826     }
00827     m_in_simulator_control = true;
00828 
00829     sc_time until_t = m_curr_time + duration;
00830 
00831     m_until_event->cancel();  // to be on the safe side
00832     m_until_event->notify_internal( duration );
00833 
00834     sc_time t;
00835 
00836     // IF DURATION WAS ZERO WE ONLY CRUNCH:
00837     //
00838     // We duplicate the code so that we don't add the overhead of the
00839     // check to each loop in the do below.
00840     if ( duration == SC_ZERO_TIME ) 
00841     {
00842         m_runnable->toggle();
00843     crunch( true );
00844     if( m_error ) return;
00845     if( m_something_to_trace ) trace_cycle( /* delta cycle? */ false );
00846     if( m_forced_stop ) 
00847         do_sc_stop_action(); 
00848     return;
00849     }
00850 
00851 
00852     // NON-ZERO DURATION: EXECUTE UP TO THAT TIME:
00853     do {
00854     m_runnable->toggle();
00855 
00856     crunch();
00857     if( m_error ) {
00858         m_in_simulator_control = false;
00859         return;
00860     }
00861     if( m_something_to_trace ) {
00862         trace_cycle( false );
00863     }
00864     // check for call(s) to sc_stop
00865     if( m_forced_stop ) {
00866         do_sc_stop_action();
00867         return;
00868     }
00869     
00870     do {
00871             t = next_time();
00872 
00873         // PROCESS TIMED NOTIFICATIONS
00874 
00875         do {
00876         sc_event_timed* et = m_timed_events->extract_top();
00877         sc_event* e = et->event();
00878         delete et;
00879         if( e != 0 ) {
00880             e->trigger();
00881         }
00882         } while( m_timed_events->size() &&
00883              m_timed_events->top()->notify_time() == t );
00884 
00885     } while( m_runnable->is_empty() && t != until_t );
00886     if ( t > m_curr_time ) m_curr_time = t;
00887 
00888     } while( t != until_t );
00889     m_in_simulator_control = false;
00890 }
00891 
00892 void
00893 sc_simcontext::do_sc_stop_action()
00894 {
00895     ::std::cout << "SystemC: simulation stopped by user." << ::std::endl;
00896     if (m_start_of_simulation_called) {
00897     end();
00898     m_in_simulator_control = false;
00899     }
00900 }
00901 
00902 
00903 //------------------------------------------------------------------------------
00904 //"sc_simcontext::stop"
00905 //
00906 // This method stops the simulator after some amount of further processing.
00907 // How much processing is done depends upon the value of the global variable
00908 // stop_mode:
00909 //     SC_STOP_IMMEDIATE - aborts the execution phase of the current delta
00910 //                         cycle and performs whatever updates are pending.
00911 //     SC_STOP_FINISH_DELTA - finishes the current delta cycle - both execution
00912 //                            and updates.
00913 // If sc_stop is called outside of the purview of the simulator kernel 
00914 // (e.g., directly from sc_main), the end of simulation notifications 
00915 // are performed. From within the purview of the simulator kernel, these
00916 // will be performed at a later time.
00917 //------------------------------------------------------------------------------
00918 
00919 void
00920 sc_simcontext::stop()
00921 {
00922     static bool stop_warning_issued = false;
00923     if (m_forced_stop)
00924     {
00925         if ( !stop_warning_issued )
00926         {
00927             stop_warning_issued = true; // This must be before the WARNING!!!
00928             SC_REPORT_WARNING(SC_ID_SIMULATION_STOP_CALLED_TWICE_, "");
00929         }
00930         return;
00931     }
00932     if ( stop_mode == SC_STOP_IMMEDIATE ) m_runnable->init();
00933     m_forced_stop = true;
00934     if ( !m_in_simulator_control  )
00935     {
00936         do_sc_stop_action();
00937     } 
00938 }
00939 
00940 void
00941 sc_simcontext::reset()
00942 {
00943     clean();
00944     init();
00945 }
00946 
00947 void
00948 sc_simcontext::end()
00949 {
00950     m_ready_to_simulate = false;
00951     m_port_registry->simulation_done();
00952     m_export_registry->simulation_done();
00953     m_prim_channel_registry->simulation_done();
00954     m_module_registry->simulation_done();
00955     m_end_of_simulation_called = true;
00956 }
00957 
00958 void
00959 sc_simcontext::hierarchy_push( sc_module* mod )
00960 {
00961     m_object_manager->hierarchy_push( mod );
00962 }
00963 
00964 sc_module*
00965 sc_simcontext::hierarchy_pop()
00966 {
00967     return DCAST<sc_module*>( m_object_manager->hierarchy_pop() );
00968 }
00969 
00970 sc_module*
00971 sc_simcontext::hierarchy_curr() const
00972 {
00973     return DCAST<sc_module*>( m_object_manager->hierarchy_curr() );
00974 }
00975     
00976 sc_object*
00977 sc_simcontext::first_object()
00978 {
00979     return m_object_manager->first_object();
00980 }
00981 
00982 sc_object*
00983 sc_simcontext::next_object()
00984 {
00985     return m_object_manager->next_object();
00986 }
00987 
00988 sc_object*
00989 sc_simcontext::find_object( const char* name )
00990 {
00991     static bool warn_find_object=true;
00992     if ( warn_find_object )
00993     {
00994     warn_find_object = false;
00995     SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
00996         "sc_simcontext::find_object() is deprecated,\n" \
00997             " use sc_find_object()" );
00998     }
00999     return m_object_manager->find_object( name );
01000 }
01001 
01002 // to generate unique names for objects in an MT-Safe way
01003 
01004 const char*
01005 sc_simcontext::gen_unique_name( const char* basename_, bool preserve_first )
01006 {
01007     return m_name_gen->gen_unique_name( basename_, preserve_first );
01008 }
01009 
01010 
01011 sc_process_handle 
01012 sc_simcontext::create_cthread_process( 
01013     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,         
01014     sc_process_host* host_p, const sc_spawn_options* opt_p )
01015 {
01016     sc_cthread_handle handle = 
01017         new sc_cthread_process(name_p, free_host, method_p, host_p, opt_p);
01018     if ( m_ready_to_simulate ) 
01019     {
01020     handle->prepare_for_simulation();
01021     } else {
01022     m_process_table->push_front( handle );
01023     }
01024     return sc_process_handle(handle);
01025 }
01026 
01027 
01028 sc_process_handle 
01029 sc_simcontext::create_method_process( 
01030     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,         
01031     sc_process_host* host_p, const sc_spawn_options* opt_p )
01032 {
01033     sc_method_handle handle = 
01034         new sc_method_process(name_p, free_host, method_p, host_p, opt_p);
01035     if ( m_ready_to_simulate ) {
01036     if ( !handle->dont_initialize() ) {
01037         push_runnable_method( handle );
01038     }
01039     } else {
01040     m_process_table->push_front( handle );
01041     }
01042     return sc_process_handle(handle);
01043 }
01044 
01045 
01046 sc_process_handle 
01047 sc_simcontext::create_thread_process( 
01048     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,         
01049     sc_process_host* host_p, const sc_spawn_options* opt_p )
01050 {
01051     sc_thread_handle handle = 
01052         new sc_thread_process(name_p, free_host, method_p, host_p, opt_p);
01053     if ( m_ready_to_simulate ) {
01054     handle->prepare_for_simulation();
01055     if ( !handle->dont_initialize() ) {
01056         push_runnable_thread( handle );
01057     }
01058     } else {
01059     m_process_table->push_front( handle );
01060     }
01061     return sc_process_handle(handle);
01062 }
01063 
01064 void
01065 sc_simcontext::add_trace_file( sc_trace_file* tf )
01066 {
01067     m_trace_files.push_back( tf );
01068     m_something_to_trace = true;
01069 }
01070 
01071 
01072 sc_cor*
01073 sc_simcontext::next_cor()
01074 {
01075     if( m_error ) {
01076     return m_cor;
01077     }
01078     
01079     sc_thread_handle thread_h = pop_runnable_thread();
01080     while( thread_h != 0 ) {
01081         if ( thread_h->ready_to_run() ) break;
01082     thread_h = pop_runnable_thread();
01083     }
01084     
01085     if( thread_h != 0 ) {
01086     return thread_h->m_cor_p;
01087     } else {
01088     return m_cor;
01089     }
01090 }
01091 
01092 
01093 const ::std::vector<sc_object*>&
01094 sc_simcontext::get_child_objects() const
01095 {
01096     static bool warn_get_child_objects=true;
01097     if ( warn_get_child_objects )
01098     {
01099     warn_get_child_objects = false;
01100     SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01101         "sc_simcontext::get_child_objects() is deprecated,\n" \
01102             " use sc_get_top_level_objects()" );
01103     }
01104     return m_child_objects;
01105 }
01106 
01107 void
01108 sc_simcontext::add_child_object( sc_object* object_ )
01109 {
01110     // no check if object_ is already in the set
01111     m_child_objects.push_back( object_ );
01112 }
01113 
01114 void
01115 sc_simcontext::remove_child_object( sc_object* object_ )
01116 {
01117     int size = m_child_objects.size();
01118     for( int i = 0; i < size; ++ i ) {
01119     if( object_ == m_child_objects[i] ) {
01120         m_child_objects[i] = m_child_objects[size - 1];
01121         m_child_objects.resize(size-1);
01122         return;
01123     }
01124     }
01125     // no check if object_ is really in the set
01126 }
01127 
01128 sc_dt::uint64
01129 sc_simcontext::delta_count() const
01130 {
01131     static bool warn_delta_count=true;
01132     if ( warn_delta_count )
01133     {
01134     warn_delta_count = false;
01135     SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01136         "sc_simcontext::delta_count() is deprecated, use sc_delta_count()" );
01137     }
01138     return m_delta_count;
01139 }
01140 
01141 bool
01142 sc_simcontext::is_running() const
01143 {
01144     static bool warn_is_running=true;
01145     if ( warn_is_running )
01146     {
01147     warn_is_running = false;
01148     SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01149         "sc_simcontext::is_running() is deprecated, use sc_is_running()" );
01150     }
01151     return m_ready_to_simulate;
01152 }
01153 
01154 const sc_time
01155 sc_simcontext::next_time()
01156 {
01157     while( m_timed_events->size() ) {
01158     sc_event_timed* et = m_timed_events->top();
01159     if( et->event() != 0 ) {
01160         return et->notify_time();
01161     }
01162     delete m_timed_events->extract_top();
01163     }
01164     return SC_ZERO_TIME;
01165 }
01166 
01167 
01168 void
01169 sc_simcontext::remove_delta_event( sc_event* e )
01170 {
01171     int i = e->m_delta_event_index;
01172     int j = m_delta_events.size() - 1;
01173     assert( i >= 0 && i <= j );
01174     if( i != j ) {
01175     sc_event** l_delta_events = &m_delta_events[0];
01176     l_delta_events[i] = l_delta_events[j];
01177     l_delta_events[i]->m_delta_event_index = i;
01178     }
01179     m_delta_events.resize(m_delta_events.size()-1);
01180     e->m_delta_event_index = -1;
01181 }
01182 
01183 
01184 void
01185 sc_simcontext::trace_cycle( bool delta_cycle )
01186 {
01187     int size;
01188     if( ( size = m_trace_files.size() ) != 0 ) {
01189     sc_trace_file** l_trace_files = &m_trace_files[0];
01190     int i = size - 1;
01191     do {
01192         l_trace_files[i]->cycle( delta_cycle );
01193     } while( -- i >= 0 );
01194     }
01195 }
01196 
01197 // ----------------------------------------------------------------------------
01198 
01199 #if 1
01200 #ifdef PURIFY
01201     static sc_simcontext sc_default_global_context;
01202     sc_simcontext* sc_curr_simcontext = &sc_default_global_context;
01203 #else
01204     sc_simcontext* sc_curr_simcontext = 0;
01205     sc_simcontext* sc_default_global_context = 0;
01206 #endif
01207 #else
01208 // Not MT-safe!
01209 static sc_simcontext* sc_curr_simcontext = 0;
01210 
01211 
01212 sc_simcontext*
01213 sc_get_curr_simcontext()
01214 {
01215     if( sc_curr_simcontext == 0 ) {
01216 #ifdef PURIFY
01217         static sc_simcontext sc_default_global_context;
01218         sc_curr_simcontext = &sc_default_global_context;
01219 #else
01220         static sc_simcontext* sc_default_global_context = new sc_simcontext;
01221         sc_curr_simcontext = sc_default_global_context;
01222 #endif
01223     }
01224     return sc_curr_simcontext;
01225 }
01226 #endif // 0
01227 
01228 // Generates unique names within each module.
01229 
01230 const char*
01231 sc_gen_unique_name( const char* basename_, bool preserve_first )
01232 {
01233     sc_simcontext* simc = sc_get_curr_simcontext();
01234     sc_module* curr_module = simc->hierarchy_curr();
01235     if( curr_module != 0 ) {
01236     return curr_module->gen_unique_name( basename_, preserve_first );
01237     } else {
01238         sc_process_b* curr_proc_p = sc_get_current_process_b();
01239     if ( curr_proc_p )
01240     {
01241         return curr_proc_p->gen_unique_name( basename_, preserve_first );
01242     }
01243     else
01244     {
01245         return simc->gen_unique_name( basename_, preserve_first );
01246     }
01247     }
01248 }
01249 
01250 // Get a handle for the current process
01251 //
01252 // Note that this method should not be called if the current process is
01253 // in the act of being deleted, it will mess up the reference count management
01254 // of sc_process_b instance the handle represents. Instead, use the a 
01255 // pointer to the raw sc_process_b instance, which may be acquired via
01256 // sc_get_current_process_b().
01257 
01258 sc_process_handle
01259 sc_get_current_process_handle()
01260 {
01261     return ( sc_is_running() ) ?
01262     sc_process_handle(sc_get_current_process_b()) : 
01263     sc_get_last_created_process_handle();
01264 }
01265 
01266 // THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
01267 sc_process_b*
01268 sc_get_curr_process_handle()
01269 {
01270     static bool warn=true;
01271     if ( warn )
01272     {
01273         warn = false;
01274         SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01275        "sc_get_curr_process_handle deprecated use sc_get_current_process_handle"
01276        );
01277     }
01278 
01279     return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
01280 }
01281 
01282 // Return indication if there are more processes to execute in this delta phase
01283 
01284 bool
01285 sc_pending_activity_at_current_time()
01286 {
01287     sc_simcontext* c_p = sc_get_curr_simcontext();
01288     return (c_p->m_delta_events.size() != 0) ||
01289             !c_p->m_runnable->is_empty() ||
01290         c_p->m_prim_channel_registry->pending_updates();
01291 }
01292 
01293 // Set the random seed for controlled randomization -- not yet implemented
01294 
01295 void
01296 sc_set_random_seed( unsigned int )
01297 {
01298     SC_REPORT_WARNING( SC_ID_NOT_IMPLEMENTED_,
01299                "void sc_set_random_seed( unsigned int )" );
01300 }
01301 
01302 
01303 void
01304 sc_start( const sc_time& duration )
01305 {
01306     sc_simcontext* context;
01307     int status;
01308 
01309     context = sc_get_curr_simcontext();
01310     status = context->sim_status();
01311     if( status != SC_SIM_OK ) 
01312     {
01313     if ( status == SC_SIM_USER_STOP )
01314     {
01315         SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_STOP_, "");        
01316     }
01317         return;
01318     }
01319     context->simulate( duration );
01320 }
01321 
01322 void
01323 sc_start()  
01324 {
01325     sc_start( sc_time(~sc_dt::UINT64_ZERO, false) - sc_time_stamp() );
01326 }
01327 
01328 // for backward compatibility with 1.0
01329 void
01330 sc_start( double duration )  // in default time units
01331 {
01332     static bool warn_sc_start=true;
01333     if ( warn_sc_start )
01334     {
01335     warn_sc_start = false;
01336     SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01337         "sc_start(double) deprecated, use sc_start(sc_time) or sc_start()");
01338     }
01339 
01340     if( duration == -1 )  // simulate forever
01341     {
01342         sc_start( 
01343             sc_time(~sc_dt::UINT64_ZERO, false) - sc_time_stamp() );
01344     }
01345     else
01346     {
01347         sc_start( sc_time( duration, true ) );
01348     }
01349 }
01350 
01351 void
01352 sc_stop()
01353 {
01354     sc_get_curr_simcontext()->stop();
01355 }
01356 
01357 
01358 // The following function is deprecated in favor of sc_start(SC_ZERO_TIME):
01359 
01360 void
01361 sc_initialize()
01362 {
01363     static bool warning_initialize = true;
01364 
01365     if ( warning_initialize )
01366     {
01367         warning_initialize = false;
01368         SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01369         "sc_initialize() is deprecated: use sc_start(SC_ZERO_TIME)" );
01370     }
01371     sc_get_curr_simcontext()->initialize();
01372 }
01373 
01374 // The following function has been deprecated in favor of sc_start(duration):
01375 
01376 void
01377 sc_cycle( const sc_time& duration )
01378 {
01379     static bool warning_cycle = true;
01380 
01381     if ( warning_cycle )
01382     {
01383         warning_cycle = false;
01384         SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01385         "sc_cycle is deprecated: use sc_start(sc_time)" );
01386     }
01387     sc_get_curr_simcontext()->cycle( duration );
01388 }
01389 
01390 sc_object* sc_find_object( const char* name, sc_simcontext* simc_p )
01391 {
01392     return simc_p->get_object_manager()->find_object( name );
01393 }
01394 
01395 
01396 const sc_time&
01397 sc_time_stamp()
01398 {
01399     return sc_get_curr_simcontext()->time_stamp();
01400 }
01401 
01402 double
01403 sc_simulation_time()
01404 {
01405     static bool warn_simulation_time=true;
01406     if ( warn_simulation_time )
01407     {
01408         warn_simulation_time=false;
01409         SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
01410         "sc_simulation_time() is deprecated use sc_time_stamp()" );
01411     }
01412     return sc_get_curr_simcontext()->time_stamp().to_default_time_units();
01413 }
01414 
01415 void
01416 sc_defunct_process_function( sc_module* )
01417 {
01418     // This function is pointed to by defunct sc_thread_process'es and
01419     // sc_cthread_process'es. In a correctly constructed world, this
01420     // function should never be called; hence the assert.
01421     assert( false );
01422 }
01423 
01424 //------------------------------------------------------------------------------
01425 //"sc_set_stop_mode"
01426 //
01427 // This function sets the mode of operation when sc_stop() is called.
01428 //     mode = SC_STOP_IMMEDIATE or SC_STOP_FINISH_DELTA.
01429 //------------------------------------------------------------------------------
01430 void sc_set_stop_mode(sc_stop_mode mode)
01431 {
01432     if ( sc_is_running() )
01433     {
01434         SC_REPORT_WARNING(SC_ID_STOP_MODE_AFTER_START_,"");
01435     }
01436     else
01437     {
01438         switch( mode )
01439         {
01440           case SC_STOP_IMMEDIATE:
01441           case SC_STOP_FINISH_DELTA:
01442               stop_mode = mode;
01443               break;
01444           default:
01445               break;
01446         }
01447     }
01448 }
01449 
01450 sc_stop_mode
01451 sc_get_stop_mode()
01452 {
01453     return stop_mode;
01454 }
01455 
01456 } // namespace sc_core
01457 // Taf!

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5