00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
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
00169
00170
00171
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;
00194 sc_method_handle m_method_q;
00195 sc_thread_handle m_thread_q;
00196 };
00197
00198
00199
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;
00209 sc_method_handle method_now_p;
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
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 #if 0
00238 sc_cthread_handle cthread_next_p;
00239 sc_cthread_handle cthread_now_p;
00240 sc_thread_handle thread_next_p;
00241 sc_thread_handle thread_now_p;
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;
00300 sc_cthread_handle prior_p;
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;
00321 sc_method_handle prior_p;
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;
00342 sc_thread_handle prior_p;
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
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
00410
00411
00412
00413
00414 void
00415 sc_simcontext::init()
00416 {
00417
00418
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
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
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;
00503 #endif
00504
00505 while ( true ) {
00506
00507
00508
00509 m_execution_phase = phase_evaluate;
00510 while( true ) {
00511
00512
00513
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
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
00543 if( m_forced_stop ) {
00544 if ( stop_mode == SC_STOP_IMMEDIATE ) return;
00545 }
00546
00547 if( m_runnable->is_empty() ) {
00548
00549 break;
00550 }
00551 m_runnable->toggle();
00552 }
00553
00554
00555
00556
00557
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( true );
00566 }
00567
00568
00569
00570
00571 if( m_forced_stop ) {
00572 break;
00573 }
00574
00575 #ifdef DEBUG_SYSTEMC
00576
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
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
00603 break;
00604 }
00605
00606
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( 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
00645 if( m_forced_stop ) {
00646 do_sc_stop_action();
00647 return;
00648 }
00649
00650
00651
00652
00653
00654
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
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;
00675 sc_method_handle method_p;
00676 sc_thread_handle thread_p;
00677
00678 if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) {
00679 return;
00680 }
00681
00682
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
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
00703
00704 if( m_forced_stop ) {
00705 do_sc_stop_action();
00706 return;
00707 }
00708
00709
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
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
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
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
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
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
00783
00784 crunch();
00785 if( m_error ) {
00786 return;
00787 }
00788 if( m_something_to_trace ) {
00789 trace_cycle( false );
00790 }
00791
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();
00832 m_until_event->notify_internal( duration );
00833
00834 sc_time t;
00835
00836
00837
00838
00839
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( false );
00846 if( m_forced_stop )
00847 do_sc_stop_action();
00848 return;
00849 }
00850
00851
00852
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
00865 if( m_forced_stop ) {
00866 do_sc_stop_action();
00867 return;
00868 }
00869
00870 do {
00871 t = next_time();
00872
00873
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
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
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;
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
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
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
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
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
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
01251
01252
01253
01254
01255
01256
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
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
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
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
01329 void
01330 sc_start( double duration )
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 )
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
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
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
01419
01420
01421 assert( false );
01422 }
01423
01424
01425
01426
01427
01428
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 }
01457