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 #ifndef SC_PROCESS_INT_H
00044 #define SC_PROCESS_INT_H
00045
00046 #include "sysc/kernel/sc_cor.h"
00047 #include "sysc/kernel/sc_except.h"
00048 #include "sysc/kernel/sc_lambda.h"
00049 #include "sysc/kernel/sc_module.h"
00050 #include "sysc/kernel/sc_process_b.h"
00051 #include "sysc/utils/sc_list.h"
00052
00053 namespace sc_core {
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 inline
00067 bool
00068 sc_process_b::do_initialize() const
00069 {
00070 return m_do_initialize;
00071 }
00072
00073 inline
00074 void
00075 sc_process_b::do_initialize( bool do_initialize_ )
00076 {
00077 m_do_initialize = do_initialize_;
00078 }
00079
00080
00081 inline
00082 bool
00083 sc_process_b::is_runnable()
00084 {
00085 return m_runnable_p != 0;
00086 }
00087
00088
00089 inline
00090 void
00091 sc_process_b::execute()
00092 {
00093 #ifndef SC_USE_MEMBER_FUNC_PTR
00094 entry_fn->invoke( host );
00095 #else
00096 (host->*entry_fn)();
00097 #endif
00098 }
00099
00100
00101 inline
00102 bool
00103 sc_process_b::trigger_static()
00104 {
00105 return ( !is_runnable() && m_trigger_type == STATIC );
00106 }
00107
00108
00109 inline
00110 bool
00111 sc_process_b::timed_out() const
00112 {
00113 return m_timed_out;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123 class sc_method_process
00124 : public sc_process_b
00125 {
00126 friend class sc_event;
00127 friend class sc_module;
00128 friend class sc_process_host;
00129 friend class sc_process_table;
00130 friend class sc_simcontext;
00131 friend class sc_runnable;
00132
00133 friend void next_trigger( sc_simcontext* );
00134 friend void next_trigger( const sc_event&,
00135 sc_simcontext* );
00136 friend void next_trigger( sc_event_or_list&,
00137 sc_simcontext* );
00138 friend void next_trigger( sc_event_and_list&,
00139 sc_simcontext* );
00140 friend void next_trigger( const sc_time&,
00141 sc_simcontext* );
00142 friend void next_trigger( const sc_time&, const sc_event&,
00143 sc_simcontext* );
00144 friend void next_trigger( const sc_time&, sc_event_or_list&,
00145 sc_simcontext* );
00146 friend void next_trigger( const sc_time&, sc_event_and_list&,
00147 sc_simcontext* );
00148
00149 public:
00150
00151 virtual const char* kind() const
00152 { return "sc_method_process"; }
00153
00154 protected:
00155
00156 sc_method_process( const char* nm,
00157 SC_ENTRY_FUNC fn,
00158 sc_process_host* host );
00159 virtual ~sc_method_process();
00160
00161 void clear_trigger();
00162
00163 void next_trigger( const sc_event& );
00164 void next_trigger( sc_event_or_list& );
00165 void next_trigger( sc_event_and_list& );
00166 void next_trigger( const sc_time& );
00167 void next_trigger( const sc_time&, const sc_event& );
00168 void next_trigger( const sc_time&, sc_event_or_list& );
00169 void next_trigger( const sc_time&, sc_event_and_list& );
00170
00171 bool trigger_dynamic( sc_event* );
00172
00173 void set_next_exist( sc_method_handle next_p );
00174 sc_method_handle next_exist();
00175 void set_next_runnable( sc_method_handle next_p );
00176 sc_method_handle next_runnable();
00177
00178 };
00179
00180
00181
00182
00183 inline
00184 void
00185 sc_method_process::next_trigger( const sc_event& e )
00186 {
00187 clear_trigger();
00188 e.add_dynamic( this );
00189 m_event = &e;
00190 m_trigger_type = EVENT;
00191 }
00192
00193 inline
00194 void
00195 sc_method_process::next_trigger( sc_event_or_list& el )
00196 {
00197 clear_trigger();
00198 el.add_dynamic( this );
00199 m_event_list = ⪙
00200 m_trigger_type = OR_LIST;
00201 }
00202
00203 inline
00204 void
00205 sc_method_process::next_trigger( sc_event_and_list& el )
00206 {
00207 clear_trigger();
00208 el.add_dynamic( this );
00209 m_event_list = ⪙
00210 m_event_count = el.size();
00211 m_trigger_type = AND_LIST;
00212 }
00213
00214 inline
00215 void
00216 sc_method_process::next_trigger( const sc_time& t )
00217 {
00218 clear_trigger();
00219 m_timeout_event.notify_delayed( t );
00220 m_timeout_event.add_dynamic( this );
00221 m_trigger_type = TIMEOUT;
00222 }
00223
00224 inline
00225 void
00226 sc_method_process::next_trigger( const sc_time& t, const sc_event& e )
00227 {
00228 clear_trigger();
00229 m_timeout_event.notify_delayed( t );
00230 m_timeout_event.add_dynamic( this );
00231 e.add_dynamic( this );
00232 m_event = &e;
00233 m_trigger_type = EVENT_TIMEOUT;
00234 }
00235
00236 inline
00237 void
00238 sc_method_process::next_trigger( const sc_time& t, sc_event_or_list& el )
00239 {
00240 clear_trigger();
00241 m_timeout_event.notify_delayed( t );
00242 m_timeout_event.add_dynamic( this );
00243 el.add_dynamic( this );
00244 m_event_list = ⪙
00245 m_trigger_type = OR_LIST_TIMEOUT;
00246 }
00247
00248 inline
00249 void
00250 sc_method_process::next_trigger( const sc_time& t, sc_event_and_list& el )
00251 {
00252 clear_trigger();
00253 m_timeout_event.notify_delayed( t );
00254 m_timeout_event.add_dynamic( this );
00255 el.add_dynamic( this );
00256 m_event_list = ⪙
00257 m_event_count = el.size();
00258 m_trigger_type = AND_LIST_TIMEOUT;
00259 }
00260
00261 inline
00262 void sc_method_process::set_next_exist(sc_method_handle next_p)
00263 {
00264 m_exist_p = next_p;
00265 }
00266
00267 inline
00268 sc_method_handle sc_method_process::next_exist()
00269 {
00270 return (sc_method_handle)m_exist_p;
00271 }
00272
00273
00274 inline
00275 void sc_method_process::set_next_runnable(sc_method_handle next_p)
00276 {
00277 m_runnable_p = next_p;
00278 }
00279
00280 inline
00281 sc_method_handle sc_method_process::next_runnable()
00282 {
00283 return (sc_method_handle)m_runnable_p;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293 class sc_thread_process
00294 : public sc_process_b
00295 {
00296 friend class sc_event;
00297 friend class sc_module;
00298 friend class sc_process_table;
00299 friend class sc_simcontext;
00300 friend class sc_runnable;
00301
00302 friend void wait( const sc_event&,
00303 sc_simcontext* );
00304 friend void wait( sc_event_or_list&,
00305 sc_simcontext* );
00306 friend void wait( sc_event_and_list&,
00307 sc_simcontext* );
00308 friend void wait( const sc_time&,
00309 sc_simcontext* );
00310 friend void wait( const sc_time&, const sc_event&,
00311 sc_simcontext* );
00312 friend void wait( const sc_time&, sc_event_or_list&,
00313 sc_simcontext* );
00314 friend void wait( const sc_time&, sc_event_and_list&,
00315 sc_simcontext* );
00316
00317 public:
00318
00319 virtual const char* kind() const
00320 { return "sc_thread_process"; }
00321
00322 public:
00323
00324 void add_monitor( sc_process_monitor* monitor_p );
00325 void remove_monitor( sc_process_monitor* monitor_p);
00326 void signal_monitors( int type = 0 );
00327
00328 protected:
00329
00330 friend void sc_thread_cor_fn( void* );
00331 friend void sc_cthread_cor_fn( void* );
00332
00333 sc_thread_process( const char* nm,
00334 SC_ENTRY_FUNC fn,
00335 sc_process_host* host);
00336
00337 virtual ~sc_thread_process();
00338
00339 void set_stack_size( size_t size );
00340
00341 virtual void prepare_for_simulation();
00342
00343 virtual bool ready_to_run();
00344
00345 void wait( const sc_event& );
00346 void wait( sc_event_or_list& );
00347 void wait( sc_event_and_list& );
00348 void wait( const sc_time& );
00349 void wait( const sc_time&, const sc_event& );
00350 void wait( const sc_time&, sc_event_or_list& );
00351 void wait( const sc_time&, sc_event_and_list& );
00352
00353 bool trigger_dynamic( sc_event* );
00354
00355 friend void sc_set_stack_size( sc_thread_handle, size_t );
00356
00357 void set_next_exist( sc_thread_handle next_p );
00358 sc_thread_handle next_exist();
00359 void set_next_runnable( sc_thread_handle next_p );
00360 sc_thread_handle next_runnable();
00361
00362 protected:
00363
00364 size_t m_stack_size;
00365 sc_cor* m_cor;
00366 sc_pvector<sc_process_monitor*> m_monitor_q;
00367 };
00368
00369
00370
00371
00372 inline
00373 void
00374 sc_switch_thread( sc_simcontext* simc )
00375 {
00376 simc->cor_pkg()->yield( simc->next_cor() );
00377 }
00378
00379
00380
00381
00382
00383 inline
00384 bool
00385 sc_thread_process::ready_to_run()
00386 {
00387 return true;
00388 }
00389
00390
00391 inline
00392 void
00393 sc_thread_process::wait( const sc_event& e )
00394 {
00395 e.add_dynamic( this );
00396 m_trigger_type = EVENT;
00397 sc_switch_thread( simcontext() );
00398 }
00399
00400 inline
00401 void
00402 sc_thread_process::wait( sc_event_or_list& el )
00403 {
00404 el.add_dynamic( this );
00405 m_event_list = ⪙
00406 m_trigger_type = OR_LIST;
00407 sc_switch_thread( simcontext() );
00408 }
00409
00410 inline
00411 void
00412 sc_thread_process::wait( sc_event_and_list& el )
00413 {
00414 el.add_dynamic( this );
00415 m_event_list = ⪙
00416 m_event_count = el.size();
00417 m_trigger_type = AND_LIST;
00418 sc_switch_thread( simcontext() );
00419 }
00420
00421 inline
00422 void
00423 sc_thread_process::wait( const sc_time& t )
00424 {
00425 m_timeout_event.notify_delayed( t );
00426 m_timeout_event.add_dynamic( this );
00427 m_trigger_type = TIMEOUT;
00428 sc_switch_thread( simcontext() );
00429 }
00430
00431 inline
00432 void
00433 sc_thread_process::wait( const sc_time& t, const sc_event& e )
00434 {
00435 m_timeout_event.notify_delayed( t );
00436 m_timeout_event.add_dynamic( this );
00437 e.add_dynamic( this );
00438 m_event = &e;
00439 m_trigger_type = EVENT_TIMEOUT;
00440 sc_switch_thread( simcontext() );
00441 }
00442
00443 inline
00444 void
00445 sc_thread_process::wait( const sc_time& t, sc_event_or_list& el )
00446 {
00447 m_timeout_event.notify_delayed( t );
00448 m_timeout_event.add_dynamic( this );
00449 el.add_dynamic( this );
00450 m_event_list = ⪙
00451 m_trigger_type = OR_LIST_TIMEOUT;
00452 sc_switch_thread( simcontext() );
00453 }
00454
00455 inline
00456 void
00457 sc_thread_process::wait( const sc_time& t, sc_event_and_list& el )
00458 {
00459 m_timeout_event.notify_delayed( t );
00460 m_timeout_event.add_dynamic( this );
00461 el.add_dynamic( this );
00462 m_event_list = ⪙
00463 m_event_count = el.size();
00464 m_trigger_type = AND_LIST_TIMEOUT;
00465 sc_switch_thread( simcontext() );
00466 }
00467
00468 inline
00469 void sc_thread_process::add_monitor(sc_process_monitor* monitor_p)
00470 {
00471 m_monitor_q.push_back(monitor_p);
00472 }
00473
00474
00475 inline
00476 void sc_thread_process::remove_monitor(sc_process_monitor* monitor_p)
00477 {
00478 int mon_n = m_monitor_q.size();
00479
00480 for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
00481 {
00482 if ( m_monitor_q[mon_i] == monitor_p )
00483 {
00484 m_monitor_q[mon_i] = m_monitor_q[mon_n-1];
00485 m_monitor_q.decr_count();
00486 }
00487 }
00488 }
00489
00490 inline
00491 void sc_thread_process::set_next_exist(sc_thread_handle next_p)
00492 {
00493 m_exist_p = next_p;
00494 }
00495
00496 inline
00497 sc_thread_handle sc_thread_process::next_exist()
00498 {
00499 return (sc_thread_handle)m_exist_p;
00500 }
00501
00502 inline
00503 void sc_thread_process::set_next_runnable(sc_thread_handle next_p)
00504 {
00505 m_runnable_p = next_p;
00506 }
00507
00508 inline
00509 sc_thread_handle sc_thread_process::next_runnable()
00510 {
00511 return (sc_thread_handle)m_runnable_p;
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 class sc_cthread_process
00523 : public sc_thread_process
00524 {
00525 friend class sc_module;
00526 friend class sc_process_table;
00527 friend class sc_simcontext;
00528 friend class sc_thread_process;
00529
00530 friend void wait( sc_simcontext* );
00531 friend void wait( const sc_event&,
00532 sc_simcontext* );
00533 friend void wait( sc_event_or_list&,
00534 sc_simcontext* );
00535 friend void wait( sc_event_and_list&,
00536 sc_simcontext* );
00537 friend void wait( const sc_time&,
00538 sc_simcontext* );
00539 friend void wait( const sc_time&, const sc_event&,
00540 sc_simcontext* );
00541 friend void wait( const sc_time&, sc_event_or_list&,
00542 sc_simcontext* );
00543 friend void wait( const sc_time&, sc_event_and_list&,
00544 sc_simcontext* );
00545
00546 friend void halt( sc_simcontext* );
00547 friend void wait( int,
00548 sc_simcontext* );
00549 friend void wait_until( const sc_lambda_ptr&,
00550 sc_simcontext* );
00551 friend void watching_before_simulation( const sc_lambda_ptr&,
00552 sc_simcontext* );
00553 friend void watching_during_simulation( const sc_lambda_ptr&,
00554 sc_simcontext* );
00555
00556 friend void __reset_watching( sc_cthread_handle );
00557 friend void __open_watching( sc_cthread_handle );
00558 friend void __close_watching( sc_cthread_handle );
00559 friend int __watch_level( sc_cthread_handle );
00560 friend void __watching_first( sc_cthread_handle );
00561 friend void __sanitycheck_watchlists( sc_cthread_handle );
00562
00563 void set_next_exist( sc_cthread_handle next_p );
00564 sc_cthread_handle next_exist();
00565
00566 public:
00567
00568 virtual const char* kind() const
00569 { return "sc_cthread_process"; }
00570
00571 protected:
00572 friend void sc_cthread_cor_fn( void* );
00573 virtual ~sc_cthread_process();
00574
00575 private:
00576
00577 sc_cthread_process( const char* nm,
00578 SC_ENTRY_FUNC fn,
00579 sc_process_host* host );
00580
00581 virtual bool is_cthread() const;
00582
00583 virtual void prepare_for_simulation();
00584
00585 virtual bool ready_to_run();
00586
00587
00588 bool eval_watchlist();
00589 bool eval_watchlist_curr_level();
00590
00591 void wait_halt();
00592 void wait_clock( int = 1 );
00593 void wait_lambda( const sc_lambda_ptr& );
00594 void add_lambda( const sc_lambda_ptr& );
00595
00596 void __reset_watching();
00597 void __open_watching();
00598 void __close_watching();
00599 int __watch_level() const;
00600
00601 private:
00602
00603 typedef sc_pvector<sc_plist<sc_lambda_ptr*>* > watchlists_t;
00604
00605 enum { UNKNOWN, CLOCK, LAMBDA } m_wait_state;
00606 int m_wait_cycles;
00607 sc_lambda_ptr m_wait_lambda;
00608 int m_exception_level;
00609
00610 int m_watch_level;
00611
00612 watchlists_t m_watchlists;
00613 };
00614
00615
00616
00617 inline
00618 void sc_cthread_process::set_next_exist(sc_cthread_handle next_p)
00619 {
00620 m_exist_p = next_p;
00621 }
00622
00623 inline
00624 sc_cthread_handle sc_cthread_process::next_exist()
00625 {
00626 return (sc_cthread_handle)m_exist_p;
00627 }
00628
00629
00630 inline
00631 void
00632 sc_cthread_process::wait_halt()
00633 {
00634 m_wait_cycles = 1;
00635 m_wait_state = CLOCK;
00636 sc_switch_thread( simcontext() );
00637 throw sc_halt();
00638 }
00639
00640 inline
00641 void
00642 sc_cthread_process::wait_clock( int n )
00643 {
00644 m_wait_cycles = n;
00645 m_wait_state = CLOCK;
00646 sc_switch_thread( simcontext() );
00647 m_wait_state = UNKNOWN;
00648 if( m_exception_level == 0 ) {
00649
00650 throw sc_user();
00651
00652 } else if( m_exception_level > 0 ) {
00653 throw m_exception_level;
00654 }
00655 }
00656
00657 inline
00658 void
00659 sc_cthread_process::wait_lambda( const sc_lambda_ptr& lambda )
00660 {
00661 m_wait_lambda = lambda;
00662 m_wait_state = LAMBDA;
00663 sc_switch_thread( simcontext() );
00664 m_wait_state = UNKNOWN;
00665 if( m_exception_level == 0 ) {
00666
00667 throw sc_user();
00668
00669 } else if( m_exception_level > 0 ) {
00670 throw m_exception_level;
00671 }
00672 }
00673
00674 inline
00675 void
00676 sc_cthread_process::add_lambda( const sc_lambda_ptr& lambda )
00677 {
00678 assert( m_watch_level < SC_MAX_WATCH_LEVEL );
00679 m_watchlists[m_watch_level]->push_back( new sc_lambda_ptr( lambda ) );
00680 }
00681
00682
00683 inline
00684 void
00685 sc_cthread_process::__reset_watching()
00686 {
00687 m_watch_level = 0;
00688 }
00689
00690 inline
00691 void
00692 sc_cthread_process::__open_watching()
00693 {
00694 m_watch_level ++;
00695 }
00696
00697 inline
00698 void
00699 sc_cthread_process::__close_watching()
00700 {
00701 m_watch_level --;
00702 assert( m_watch_level >= 0 );
00703 }
00704
00705 inline
00706 int
00707 sc_cthread_process::__watch_level() const
00708 {
00709 return m_watch_level;
00710 }
00711
00712 }
00713
00714 #endif
00715
00716