SystemC  Recoding Infrastructure for SystemC v0.6.0 derived from Accellera SystemC 2.3.1
Accellera SystemC proof-of-concept library
sc_prim_channel.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  sc_prim_channel.h -- Abstract base class of all primitive channel classes.
21 
22  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
23 
24  CHANGE LOG AT THE END OF THE FILE
25  *****************************************************************************/
26 
27 #ifndef SC_PRIM_CHANNEL_H
28 #define SC_PRIM_CHANNEL_H
29 
30 #include "sysc/kernel/sc_object.h"
31 #include "sysc/kernel/sc_wait.h"
33 
34 // 02/22/2015 GL: to include the definition of CHNL_MTX_TYPE_
35 #include "sysc/kernel/sc_process.h"
36 
37 namespace sc_core {
38 
39 
40 /**************************************************************************/
46 // 02/22/2015 GL.
47 
53 
57  explicit chnl_scoped_lock( CHNL_MTX_TYPE_& mtx ): m_ref( mtx )
58  {
60  if (cp) // not the root thread
61  cp->lock_and_push( &m_ref );
62  }
63 
68  {
70  if (cp) // not the root thread
71  cp->pop_and_unlock( &m_ref );
72  }
73 };
74 
75 /**************************************************************************/
82 : public sc_object
83 {
85 
86 public:
87  enum { list_end = 0xdb };
88 public:
89  virtual const char* kind() const
90  { return "sc_prim_channel"; }
91 
92  inline bool update_requested()
93  {
94  // 02/25/2015 GL: add a lock to protect concurrent communication
95  chnl_scoped_lock lock( m_mutex );
96 
97  return m_update_next_p != (sc_prim_channel*)list_end;
98  // 02/25/2015 GL: return releases the lock
99  }
100 
101  // request the update method to be executed during the update phase
102  inline void request_update();
103 
104  // request the update method to be executed during the update phase
105  // from a process external to the simulator.
106  void async_request_update();
107 
108 protected:
109 
110  // constructors
111  sc_prim_channel();
112  explicit sc_prim_channel( const char* );
113 
114  // destructor
115  virtual ~sc_prim_channel();
116 
123  // 09/21/2015 GL.
124  virtual void update();
125 
126  // called by construction_done (does nothing by default)
127  virtual void before_end_of_elaboration();
128 
129  // called by elaboration_done (does nothing by default)
130  virtual void end_of_elaboration();
131 
132  // called by start_simulation (does nothing by default)
133  virtual void start_of_simulation();
134 
135  // called by simulation_done (does nothing by default)
136  virtual void end_of_simulation();
137 
138 protected:
139 
140  // to avoid calling sc_get_curr_simcontext()
141 
142  // static sensitivity for SC_THREADs and SC_CTHREADs
143 
148  // 08/19/2015 GL: modified for the OoO simulation
149  void wait( int seg_id = -1)
150  { sc_core::wait( seg_id, simcontext() ); }
151 
152 
153  // dynamic sensitivity for SC_THREADs and SC_CTHREADs
154 
159  // 08/19/2015 GL: modified for the OoO simulation
160  void wait( const sc_event& e, int seg_id = -1)
161  { sc_core::wait( e, seg_id, simcontext() ); }
162 
167  // 08/19/2015 GL: modified for the OoO simulation
168  void wait( const sc_event_or_list& el, int seg_id = -1 )
169  { sc_core::wait( el, seg_id, simcontext() ); }
170 
175  // 08/19/2015 GL: modified for the OoO simulation
176  void wait( const sc_event_and_list& el, int seg_id = -1 )
177  { sc_core::wait( el, seg_id, simcontext() ); }
178 
183  // 08/19/2015 GL: modified for the OoO simulation
184  void wait( const sc_time& t, int seg_id = -1 )
185  { sc_core::wait( t, seg_id, simcontext() ); }
186 
191  // 08/19/2015 GL: modified for the OoO simulation
192  void wait( double v, sc_time_unit tu, int seg_id = -1 )
193  { sc_core::wait( sc_time( v, tu, simcontext() ), seg_id,
194  simcontext() ); }
195 
200  // 08/19/2015 GL: modified for the OoO simulation
201  void wait( const sc_time& t, const sc_event& e, int seg_id = -1 )
202  { sc_core::wait( t, e, seg_id, simcontext() ); }
203 
208  // 08/19/2015 GL: modified for the OoO simulation
209  void wait( double v, sc_time_unit tu, const sc_event& e, int seg_id = -1 )
210  { sc_core::wait( sc_time( v, tu, simcontext() ), e, seg_id,
211  simcontext() ); }
212 
217  // 08/19/2015 GL: modified for the OoO simulation
218  void wait( const sc_time& t, const sc_event_or_list& el, int seg_id = -1 )
219  { sc_core::wait( t, el, seg_id, simcontext() ); }
220 
225  // 08/19/2015 GL: modified for the OoO simulation
226  void wait( double v, sc_time_unit tu, const sc_event_or_list& el,
227  int seg_id = -1 )
228  { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id,
229  simcontext() ); }
230 
235  // 08/19/2015 GL: modified for the OoO simulation
236  void wait( const sc_time& t, const sc_event_and_list& el, int seg_id = -1 )
237  { sc_core::wait( t, el, seg_id, simcontext() ); }
238 
243  // 08/19/2015 GL: modified for the OoO simulation
244  void wait( double v, sc_time_unit tu, const sc_event_and_list& el,
245  int seg_id = -1 )
246  { sc_core::wait( sc_time( v, tu, simcontext() ), el, seg_id,
247  simcontext() ); }
248 
253  // 08/19/2015 GL: modified for the OoO simulation
254  void wait( int n, int seg_id = -1 )
255  { sc_core::wait( n, seg_id, simcontext() ); }
256 
257 
258  // static sensitivity for SC_METHODs
259 
264  // 08/19/2015 GL: modified for the OoO simulation
265  void next_trigger( )
267 
268 
269  // dynamic sensitivity for SC_METHODs
270 
275  // 08/19/2015 GL: modified for the OoO simulation
276  void next_trigger( const sc_event& e )
277  { sc_core::next_trigger( e, simcontext() ); }
278 
283  // 08/19/2015 GL: modified for the OoO simulation
284  void next_trigger( const sc_event_or_list& el )
285  { sc_core::next_trigger( el, simcontext() ); }
286 
291  // 08/19/2015 GL: modified for the OoO simulation
292  void next_trigger( const sc_event_and_list& el )
293  { sc_core::next_trigger( el, simcontext() ); }
294 
299  // 08/19/2015 GL: modified for the OoO simulation
300  void next_trigger( const sc_time& t )
301  { sc_core::next_trigger( t, simcontext() ); }
302 
307  // 08/19/2015 GL: modified for the OoO simulation
308  void next_trigger( double v, sc_time_unit tu )
310  simcontext() );}
311 
316  // 08/19/2015 GL: modified for the OoO simulation
317  void next_trigger( const sc_time& t, const sc_event& e )
318  { sc_core::next_trigger( t, e, simcontext() ); }
319 
324  // 08/19/2015 GL: modified for the OoO simulation
325  void next_trigger( double v, sc_time_unit tu, const sc_event& e )
327  sc_time( v, tu, simcontext() ), e, simcontext() ); }
328 
333  // 08/19/2015 GL: modified for the OoO simulation
334  void next_trigger( const sc_time& t, const sc_event_or_list& el )
335  { sc_core::next_trigger( t, el, simcontext() ); }
336 
341  // 08/19/2015 GL: modified for the OoO simulation
342  void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
344  sc_time( v, tu, simcontext() ), el, simcontext() ); }
345 
350  // 08/19/2015 GL: modified for the OoO simulation
351  void next_trigger( const sc_time& t, const sc_event_and_list& el )
352  { sc_core::next_trigger( t, el, simcontext() ); }
353 
358  // 08/19/2015 GL: modified for the OoO simulation
359  void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
361  sc_time( v, tu, simcontext() ), el, simcontext() ); }
362 
363 
364  // for SC_METHODs and SC_THREADs and SC_CTHREADs
365 
366  bool timed_out()
367  { return sc_core::timed_out( simcontext() ); }
368 
369 
370 #if 0 // @@@@####
371  // delta count maintenance
372  sc_dt::uint64 delta_count()
373  { return simcontext()->m_delta_count; }
374 #endif
375 
376 private:
377 
378  // called during the update phase of a delta cycle (if requested)
379  void perform_update();
380 
381  // called when construction is done
382  void construction_done();
383 
384  // called when elaboration is done
385  void elaboration_done();
386 
387  // called before simulation starts
388  void start_simulation();
389 
390  // called after simulation ends
391  void simulation_done();
392 
393  // disabled
395  sc_prim_channel& operator = ( const sc_prim_channel& );
396 
397 private:
398 
399  sc_prim_channel_registry* m_registry; // Update list manager.
400  sc_prim_channel* m_update_next_p; // Next entry in update list.
401 
402 protected:
403 
407  // 02/25/2015 GL.
409 };
410 
411 
412 /**************************************************************************/
421 {
422  friend class sc_simcontext;
423 
424 public:
425 
426  void insert( sc_prim_channel& );
427  void remove( sc_prim_channel& );
428 
429 
430  int size() const
431  { return m_prim_channel_vec.size(); }
432 
433  inline void request_update( sc_prim_channel& );
435 
436  bool pending_updates() const
437  {
438  return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end
440  }
441 
442  bool pending_async_updates() const;
443 
444 private:
445 
446  // constructor
447  explicit sc_prim_channel_registry( sc_simcontext& simc_ );
448 
449  // destructor
451 
452  // called during the update phase of a delta cycle
453  void perform_update();
454 
455  // called when construction is done
456  bool construction_done();
457 
458  // called when elaboration is done
459  void elaboration_done();
460 
461  // called before simulation starts
462  void start_simulation();
463 
464  // called after simulation ends
465  void simulation_done();
466 
467  // disabled
470  sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
471 
472 private:
473  class async_update_list;
474 
475  async_update_list* m_async_update_list_p; // external updates.
476  int m_construction_done; // # of constructs.
477  std::vector<sc_prim_channel*> m_prim_channel_vec; // existing channels.
478  sc_simcontext* m_simc; // simulator context.
479  sc_prim_channel* m_update_list_p; // internal updates.
480 
484  // 02/25/2015 GL.
485  CHNL_MTX_TYPE_ m_mutex;
486 };
487 
488 
489 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
490 
491 // ----------------------------------------------------------------------------
492 // CLASS : sc_prim_channel_registry
493 //
494 // Registry for all primitive channels.
495 // FOR INTERNAL USE ONLY!
496 // ----------------------------------------------------------------------------
497 
498 inline
499 void
501 {
502  // 02/25/2015 GL: add a lock to protect concurrent requests from different
503  // primitive channels
504  chnl_scoped_lock lock( m_mutex );
505 
506  prim_channel_.m_update_next_p = m_update_list_p;
507  m_update_list_p = &prim_channel_;
508  // 02/25/2015 GL: return releases the lock
509 }
510 
511 // ----------------------------------------------------------------------------
512 // CLASS : sc_prim_channel
513 //
514 // Abstract base class of all primitive channel classes.
515 // ----------------------------------------------------------------------------
516 
517 // request the update method (to be executed during the update phase)
518 
519 inline
520 void
522 {
523  // 02/25/2015 GL: add a lock to protect concurrent communication
524  chnl_scoped_lock lock( m_mutex );
525 
526  if( ! m_update_next_p ) {
527  m_registry->request_update( *this );
528  }
529  // 02/25/2015 GL: return releases the lock
530 }
531 
532 // request the update method from external to the simulator (to be executed
533 // during the update phase)
534 
535 // 02/25/2015 GL: assume this method is MT-safe and protected by
536 // async_update_list
537 inline
538 void
540 {
541  m_registry->async_request_update(*this);
542 }
543 
544 
545 // called during the update phase of a delta cycle (if requested)
546 
547 inline
548 void
549 sc_prim_channel::perform_update()
550 {
551  update();
552  m_update_next_p = 0;
553 }
554 
555 
556 } // namespace sc_core
557 
558 
559 /*****************************************************************************
560 
561  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
562  changes you are making here.
563 
564  Name, Affiliation, Date: Andy Goodrich, Forte,
565  Bishnupriya Bhattacharya, Cadence Design Systems,
566  25 August, 2003
567  Description of Modification: phase callbacks
568 
569  *****************************************************************************/
570 //$Log: sc_prim_channel.h,v $
571 //Revision 1.10 2011/08/26 21:38:32 acg
572 // Philipp A. Hartmann: removed unused switch m_construction_done.
573 //
574 //Revision 1.9 2011/08/07 19:08:01 acg
575 // Andy Goodrich: moved logs to end of file so line number synching works
576 // better between versions.
577 //
578 //Revision 1.8 2011/05/09 04:07:37 acg
579 // Philipp A. Hartmann:
580 // (1) Restore hierarchy in all phase callbacks.
581 // (2) Ensure calls to before_end_of_elaboration.
582 //
583 //Revision 1.7 2011/05/05 17:44:01 acg
584 // Philip A. Hartmann: change in the name of pending_async_updates.
585 //
586 //Revision 1.6 2011/04/19 15:03:48 acg
587 // Philipp A. Hartmann: remove ASYNC_UPDATE preprocessor check from header.
588 //
589 //Revision 1.5 2011/04/19 02:36:26 acg
590 // Philipp A. Hartmann: new aysnc_update and mutex support.
591 //
592 //Revision 1.4 2011/04/05 20:48:09 acg
593 // Andy Goodrich: changes to make sure that event(), posedge() and negedge()
594 // only return true if the clock has not moved.
595 //
596 //Revision 1.3 2011/02/18 20:23:45 acg
597 // Andy Goodrich: Copyright update.
598 //
599 //Revision 1.2 2011/01/20 16:52:15 acg
600 // Andy Goodrich: changes for IEEE 1666 2011.
601 //
602 //Revision 1.1.1.1 2006/12/15 20:20:04 acg
603 //SystemC 2.3
604 //
605 //Revision 1.3 2006/05/08 17:52:47 acg
606 // Andy Goodrich:
607 // (1) added David Long's forward declarations for friend functions,
608 // methods, and operators to keep the Microsoft compiler happy.
609 // (2) Added delta_count() method to sc_prim_channel for use by
610 // sc_signal so that the friend declaration in sc_simcontext.h
611 // can be for a non-templated class (i.e., sc_prim_channel.)
612 //
613 //Revision 1.2 2006/01/03 23:18:26 acg
614 //Changed copyright to include 2006.
615 //
616 //Revision 1.1.1.1 2005/12/19 23:16:43 acg
617 //First check in of SystemC 2.1 into its own archive.
618 //
619 //Revision 1.10 2005/07/30 03:44:11 acg
620 //Changes from 2.1.
621 //
622 //Revision 1.9 2005/06/10 22:43:55 acg
623 //Added CVS change log annotation.
624 
625 #endif
626 
627 // Taf!
virtual void update()
The update method (does nothing by default).
sc_process_b * sc_get_current_process_b()
OR list of events.
Definition: sc_event.h:228
#define CHNL_MTX_TYPE_
Definition: sc_process.h:65
void wait(double v, sc_time_unit tu, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
virtual const char * kind() const
void wait(double v, sc_time_unit tu, const sc_event_and_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
void wait(const sc_time &t, const sc_event_and_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
bool timed_out(sc_simcontext *)
CHNL_MTX_TYPE_ m_mutex
A mutex to protect concurrent communication.
void next_trigger(const sc_time &t)
A new parameter segment ID is added for the out-of-order simulation.
AND list of events.
Definition: sc_event.h:193
void next_trigger(const sc_time &t, const sc_event &e)
A new parameter segment ID is added for the out-of-order simulation.
void wait(const sc_time &t, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
void wait(int, sc_simcontext *)
void next_trigger(const sc_event &e)
A new parameter segment ID is added for the out-of-order simulation.
void next_trigger()
A new parameter segment ID is added for the out-of-order simulation.
void insert(sc_prim_channel &)
sc_simcontext * simcontext() const
Definition: sc_object.h:85
void async_request_update(sc_prim_channel &)
virtual void end_of_simulation()
void wait(double v, sc_time_unit tu, const sc_event_or_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
virtual void start_of_simulation()
void next_trigger(const sc_time &t, const sc_event_and_list &el)
A new parameter segment ID is added for the out-of-order simulation.
User initiated dynamic process support.
Definition: sc_process.h:555
void wait(const sc_time &t, const sc_event_or_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
friend class sc_prim_channel_registry
void next_trigger(double v, sc_time_unit tu, const sc_event &e)
A new parameter segment ID is added for the out-of-order simulation.
void wait(const sc_event_or_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
The event class.
Definition: sc_event.h:260
void next_trigger(const sc_time &t, const sc_event_or_list &el)
A new parameter segment ID is added for the out-of-order simulation.
uint64_t uint64
Definition: sc_nbdefs.h:183
CHNL_MTX_TYPE_ & m_ref
A reference to the channel lock.
The simulation context.
void wait(const sc_event_and_list &el, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
void wait(const sc_time &t, const sc_event &e, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
~chnl_scoped_lock()
The destructor automatically releases the channel lock.
void wait(int n, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
void next_trigger(double v, sc_time_unit tu, const sc_event_and_list &el)
A new parameter segment ID is added for the out-of-order simulation.
void next_trigger(const sc_event_or_list &el)
A new parameter segment ID is added for the out-of-order simulation.
Registry for all primitive channels.
void lock_and_push(CHNL_MTX_TYPE_ *lock)
Acquire a new channel lock or increment the lock counter.
void request_update(sc_prim_channel &)
virtual void end_of_elaboration()
void next_trigger(sc_simcontext *)
A new parameter segment ID is added for the out-of-order simulation.
void wait(int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
void wait(const sc_event &e, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
virtual void before_end_of_elaboration()
void next_trigger(double v, sc_time_unit tu, const sc_event_or_list &el)
A new parameter segment ID is added for the out-of-order simulation.
void next_trigger(double v, sc_time_unit tu)
A new parameter segment ID is added for the out-of-order simulation.
The chnl_scoped_lock class to lock (and automatically release) a mutex.
void next_trigger(const sc_event_and_list &el)
A new parameter segment ID is added for the out-of-order simulation.
void pop_and_unlock(CHNL_MTX_TYPE_ *lock)
Release a channel lock or decrement the lock counter.
void wait(double v, sc_time_unit tu, const sc_event &e, int seg_id=-1)
A new parameter segment ID is added for the out-of-order simulation.
Abstract base class of all primitive channel classes.
Abstract base class of all SystemC `simulation&#39; objects.
Definition: sc_object.h:51
chnl_scoped_lock(CHNL_MTX_TYPE_ &mtx)
The constructor automatically acquires the channel lock.
sc_time_unit
Definition: sc_time.h:56