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 #ifndef SC_PRIM_CHANNEL_H
00028 #define SC_PRIM_CHANNEL_H
00029
00030 #include "sysc/kernel/sc_object.h"
00031 #include "sysc/kernel/sc_wait.h"
00032 #include "sysc/kernel/sc_wait_cthread.h"
00033
00034
00035 #include "sysc/kernel/sc_process.h"
00036
00037 namespace sc_core {
00038
00039
00040
00046
00047
00048 struct chnl_scoped_lock {
00052 CHNL_MTX_TYPE_& m_ref;
00053
00057 explicit chnl_scoped_lock( CHNL_MTX_TYPE_& mtx ): m_ref( mtx )
00058 {
00059 sc_process_b* cp = sc_get_current_process_b();
00060 if (cp)
00061 cp->lock_and_push( &m_ref );
00062 }
00063
00067 ~chnl_scoped_lock()
00068 {
00069 sc_process_b* cp = sc_get_current_process_b();
00070 if (cp)
00071 cp->pop_and_unlock( &m_ref );
00072 }
00073 };
00074
00075
00081 class sc_prim_channel
00082 : public sc_object
00083 {
00084 friend class sc_prim_channel_registry;
00085
00086 public:
00087 enum { list_end = 0xdb };
00088 public:
00089 virtual const char* kind() const
00090 { return "sc_prim_channel"; }
00091
00092 inline bool update_requested()
00093 {
00094
00095 chnl_scoped_lock lock( m_mutex );
00096
00097 return m_update_next_p != (sc_prim_channel*)list_end;
00098
00099 }
00100
00101
00102 inline void request_update();
00103
00104
00105
00106 void async_request_update();
00107
00108 protected:
00109
00110
00111 sc_prim_channel();
00112 explicit sc_prim_channel( const char* );
00113
00114
00115 virtual ~sc_prim_channel();
00116
00123
00124 virtual void update();
00125
00126
00127 virtual void before_end_of_elaboration();
00128
00129
00130 virtual void end_of_elaboration();
00131
00132
00133 virtual void start_of_simulation();
00134
00135
00136 virtual void end_of_simulation();
00137
00138 protected:
00139
00140
00141
00142
00143
00148
00149 void wait( int seg_id )
00150 { sc_core::wait( seg_id, simcontext() ); }
00151
00152
00153
00154
00159
00160 void wait( const sc_event& e, int seg_id )
00161 { sc_core::wait( e, seg_id, simcontext() ); }
00162
00167
00168 void wait( const sc_event_or_list& el, int seg_id )
00169 { sc_core::wait( el, seg_id, simcontext() ); }
00170
00175
00176 void wait( const sc_event_and_list& el, int seg_id )
00177 { sc_core::wait( el, seg_id, simcontext() ); }
00178
00183
00184 void wait( const sc_time& t, int seg_id )
00185 { sc_core::wait( t, seg_id, simcontext() ); }
00186
00191
00192 void wait( double v, sc_time_unit tu, int seg_id )
00193 { sc_core::wait( sc_time( v, tu, simcontext() ), seg_id,
00194 simcontext() ); }
00195
00200
00201 void wait( const sc_time& t, const sc_event& e, int seg_id )
00202 { sc_core::wait( t, e, seg_id, simcontext() ); }
00203
00208
00209 void wait( double v, sc_time_unit tu, const sc_event& e, int seg_id )
00210 { sc_core::wait( sc_time( v, tu, simcontext() ), e, seg_id,
00211 simcontext() ); }
00212
00217
00218 void wait( const sc_time& t, const sc_event_or_list& el, int seg_id )
00219 { sc_core::wait( t, el, seg_id, simcontext() ); }
00220
00225
00226 void wait( double v, sc_time_unit tu, const sc_event_or_list& el,
00227 int seg_id )
00228 { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id,
00229 simcontext() ); }
00230
00235
00236 void wait( const sc_time& t, const sc_event_and_list& el, int seg_id )
00237 { sc_core::wait( t, el, seg_id, simcontext() ); }
00238
00243
00244 void wait( double v, sc_time_unit tu, const sc_event_and_list& el,
00245 int seg_id )
00246 { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id,
00247 simcontext() ); }
00248
00253
00254 void wait( int n, int seg_id )
00255 { sc_core::wait( n, seg_id, simcontext() ); }
00256
00257
00258
00259
00264
00265 void next_trigger( int seg_id )
00266 { sc_core::next_trigger( seg_id, simcontext() ); }
00267
00268
00269
00270
00275
00276 void next_trigger( const sc_event& e, int seg_id )
00277 { sc_core::next_trigger( e, seg_id, simcontext() ); }
00278
00283
00284 void next_trigger( const sc_event_or_list& el, int seg_id )
00285 { sc_core::next_trigger( el, seg_id, simcontext() ); }
00286
00291
00292 void next_trigger( const sc_event_and_list& el, int seg_id )
00293 { sc_core::next_trigger( el, seg_id, simcontext() ); }
00294
00299
00300 void next_trigger( const sc_time& t, int seg_id )
00301 { sc_core::next_trigger( t, seg_id, simcontext() ); }
00302
00307
00308 void next_trigger( double v, sc_time_unit tu, int seg_id )
00309 {sc_core::next_trigger( sc_time( v, tu, simcontext() ), seg_id,
00310 simcontext() );}
00311
00316
00317 void next_trigger( const sc_time& t, const sc_event& e, int seg_id )
00318 { sc_core::next_trigger( t, e, seg_id, simcontext() ); }
00319
00324
00325 void next_trigger( double v, sc_time_unit tu, const sc_event& e,
00326 int seg_id )
00327 { sc_core::next_trigger(
00328 sc_time( v, tu, simcontext() ), e, seg_id, simcontext() ); }
00329
00334
00335 void next_trigger( const sc_time& t, const sc_event_or_list& el,
00336 int seg_id )
00337 { sc_core::next_trigger( t, el, seg_id, simcontext() ); }
00338
00343
00344 void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el,
00345 int seg_id )
00346 { sc_core::next_trigger(
00347 sc_time( v, tu, simcontext() ), el, seg_id, simcontext() ); }
00348
00353
00354 void next_trigger( const sc_time& t, const sc_event_and_list& el,
00355 int seg_id )
00356 { sc_core::next_trigger( t, el, seg_id, simcontext() ); }
00357
00362
00363 void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el,
00364 int seg_id )
00365 { sc_core::next_trigger(
00366 sc_time( v, tu, simcontext() ), el, seg_id, simcontext() ); }
00367
00368
00369
00370
00371 bool timed_out()
00372 { return sc_core::timed_out( simcontext() ); }
00373
00374
00375 #if 0 // @@@@####
00376
00377 sc_dt::uint64 delta_count()
00378 { return simcontext()->m_delta_count; }
00379 #endif
00380
00381 private:
00382
00383
00384 void perform_update();
00385
00386
00387 void construction_done();
00388
00389
00390 void elaboration_done();
00391
00392
00393 void start_simulation();
00394
00395
00396 void simulation_done();
00397
00398
00399 sc_prim_channel( const sc_prim_channel& );
00400 sc_prim_channel& operator = ( const sc_prim_channel& );
00401
00402 private:
00403
00404 sc_prim_channel_registry* m_registry;
00405 sc_prim_channel* m_update_next_p;
00406
00407 protected:
00408
00412
00413 mutable CHNL_MTX_TYPE_ m_mutex;
00414 };
00415
00416
00417
00425 class sc_prim_channel_registry
00426 {
00427 friend class sc_simcontext;
00428
00429 public:
00430
00431 void insert( sc_prim_channel& );
00432 void remove( sc_prim_channel& );
00433
00434
00435 int size() const
00436 { return m_prim_channel_vec.size(); }
00437
00438 inline void request_update( sc_prim_channel& );
00439 void async_request_update( sc_prim_channel& );
00440
00441 bool pending_updates() const
00442 {
00443 return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end
00444 || pending_async_updates();
00445 }
00446
00447 bool pending_async_updates() const;
00448
00449 private:
00450
00451
00452 explicit sc_prim_channel_registry( sc_simcontext& simc_ );
00453
00454
00455 ~sc_prim_channel_registry();
00456
00457
00458 void perform_update();
00459
00460
00461 bool construction_done();
00462
00463
00464 void elaboration_done();
00465
00466
00467 void start_simulation();
00468
00469
00470 void simulation_done();
00471
00472
00473 sc_prim_channel_registry();
00474 sc_prim_channel_registry( const sc_prim_channel_registry& );
00475 sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
00476
00477 private:
00478 class async_update_list;
00479
00480 async_update_list* m_async_update_list_p;
00481 int m_construction_done;
00482 std::vector<sc_prim_channel*> m_prim_channel_vec;
00483 sc_simcontext* m_simc;
00484 sc_prim_channel* m_update_list_p;
00485
00489
00490 CHNL_MTX_TYPE_ m_mutex;
00491 };
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 inline
00504 void
00505 sc_prim_channel_registry::request_update( sc_prim_channel& prim_channel_ )
00506 {
00507
00508
00509 chnl_scoped_lock lock( m_mutex );
00510
00511 prim_channel_.m_update_next_p = m_update_list_p;
00512 m_update_list_p = &prim_channel_;
00513
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 inline
00525 void
00526 sc_prim_channel::request_update()
00527 {
00528
00529 chnl_scoped_lock lock( m_mutex );
00530
00531 if( ! m_update_next_p ) {
00532 m_registry->request_update( *this );
00533 }
00534
00535 }
00536
00537
00538
00539
00540
00541
00542 inline
00543 void
00544 sc_prim_channel::async_request_update()
00545 {
00546 m_registry->async_request_update(*this);
00547 }
00548
00549
00550
00551
00552 inline
00553 void
00554 sc_prim_channel::perform_update()
00555 {
00556 update();
00557 m_update_next_p = 0;
00558 }
00559
00560
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 #endif
00631
00632