SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_port.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_port.h -- Base classes of all port classes.
21 
22  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
23 
24  CHANGE LOG IS AT THE END OF THE FILE
25  *****************************************************************************/
26 
27 #ifndef SC_PORT_H
28 #define SC_PORT_H
29 
30 
33 #include "sysc/kernel/sc_event.h"
34 #include "sysc/kernel/sc_object.h"
35 #include "sysc/kernel/sc_process.h"
36 #include <typeinfo>
37 
38 #if ! defined( SC_DISABLE_VIRTUAL_BIND )
39 # define SC_VIRTUAL_ virtual
40 #else
41 # define SC_VIRTUAL_ /* non-virtual */
42 #endif
43 
44 namespace sc_core {
45 
46 class sc_event_finder;
47 
48 struct sc_bind_info;
49 
51 {
52  SC_ONE_OR_MORE_BOUND, // Default
55 };
56 
57 
58 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59 // BEWARE: Ports can only be created and bound during elaboration.
60 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
61 
62 
63 // ----------------------------------------------------------------------------
64 // CLASS : sc_port_base
65 //
66 // Abstract base class for class sc_port_b.
67 // ----------------------------------------------------------------------------
68 
70 : public sc_object
71 {
72  friend class sc_module;
73  friend class sc_port_registry;
74  friend class sc_sensitive;
75  friend class sc_sensitive_pos;
76  friend class sc_sensitive_neg;
77 
78 public:
79 
80  // typedefs
81 
83 
84 public:
85 
86  int bind_count();
87 
88  // get the first interface without checking for nil
89  virtual sc_interface* get_interface() = 0;
90  virtual const sc_interface* get_interface() const = 0;
91 
92  virtual const char* kind() const
93  { return "sc_port_base"; }
94 
95 protected:
96 
97  // constructors
98  explicit sc_port_base( int max_size_,
100  sc_port_base( const char* name_, int max_size_,
102 
103  // destructor
104  virtual ~sc_port_base();
105 
106  // bind interface to this port
107  void bind( sc_interface& interface_ );
108 
109  // bind parent port to this port
110  void bind( this_type& parent_ );
111 
112  // called by pbind (for internal use only)
113  virtual int vbind( sc_interface& ) = 0;
114  virtual int vbind( sc_port_base& ) = 0;
115 
116  // called by complete_binding (for internal use only)
117  virtual void add_interface( sc_interface* ) = 0;
118  virtual int interface_count() = 0;
119  virtual const char* if_typename() const = 0;
120 
121  // called by construction_done (does nothing by default)
122  virtual void before_end_of_elaboration();
123 
124  // called by elaboration_done (does nothing)
125  virtual void end_of_elaboration();
126 
127  // called by start_simulation (does nothing by default)
128  virtual void start_of_simulation();
129 
130  // called by simulation_done (does nothing by default)
131  virtual void end_of_simulation();
132 
133  // error reporting
134  void report_error( const char* id, const char* add_msg = 0) const;
135 
136 protected:
137  // called by the sc_sensitive* classes
138  virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
139  virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
140  void add_static_event(
141  sc_method_handle process_p, const sc_event& event) const;
142  void add_static_event(
143  sc_thread_handle process_p, const sc_event& event) const;
144 
145 private:
146 
147  // called by class sc_module for positional binding
148  int pbind( sc_interface& );
149  int pbind( sc_port_base& );
150 
151 
152  // support methods
153  int first_parent();
154  void insert_parent( int );
155 
156  // called when construction is done
157  void construction_done();
158 
159  // called when elaboration is done
160  void complete_binding();
161  void elaboration_done();
162 
163  // called before simulation starts
164  void start_simulation();
165 
166  // called after simulation ends
167  void simulation_done();
168 
169 protected:
170 
171  sc_bind_info* m_bind_info;
172 
173 private:
174 
175  // disabled
176  sc_port_base();
177  sc_port_base( const this_type& );
178  this_type& operator = ( const this_type& );
179 };
180 
181 
182 // ----------------------------------------------------------------------------
183 // CLASS : sc_port_registry
184 //
185 // Registry for all ports.
186 // FOR INTERNAL USE ONLY!
187 // ----------------------------------------------------------------------------
188 
190 {
191  friend class sc_simcontext;
192 
193 public:
194 
195  void insert( sc_port_base* );
196  void remove( sc_port_base* );
197 
198  int size() const
199  { return m_port_vec.size(); }
200 
201 private:
202 
203  // constructor
204  explicit sc_port_registry( sc_simcontext& simc_ );
205 
206  // destructor
207  ~sc_port_registry();
208 
209  // called when by construction_done and elaboration done
210  void complete_binding();
211 
212  // called when construction is done
213  bool construction_done();
214 
215  // called when elaboration is done
216  void elaboration_done();
217 
218  // called before simulation starts
219  void start_simulation();
220 
221  // called after simulation ends
222  void simulation_done();
223 
224  static void replace_port( sc_port_registry* );
225 
226 private:
227 
228  int m_construction_done;
229  std::vector<sc_port_base*> m_port_vec;
230  sc_simcontext* m_simc;
231 
232 private:
233 
234  // disabled
237  sc_port_registry& operator = ( const sc_port_registry& );
238 };
239 
240 
241 // ----------------------------------------------------------------------------
242 // CLASS : sc_port_b
243 //
244 // Abstract base class for class sc_port.
245 // ----------------------------------------------------------------------------
246 
247 template <class IF>
249 : public sc_port_base
250 {
251 public:
252 
253  friend class sc_sensitive;
254  friend class sc_sensitive_neg;
255  friend class sc_sensitive_pos;
256 
257  // typedefs
258 
262 
263 public:
264 
265  // bind an interface of type IF to this port
266 
267  SC_VIRTUAL_ void bind( IF& interface_ )
268  { base_type::bind( interface_ ); }
269 
270  void operator () ( IF& interface_ )
271  { this->bind( interface_ ); }
272 
273 
274  // bind a parent port with type IF to this port
275 
276  SC_VIRTUAL_ void bind( port_type& parent_ )
277  { base_type::bind( parent_ ); }
278 
279  void operator () ( port_type& parent_ )
280  { this->bind( parent_ ); }
281 
282 
283  // number of connected interfaces
284 
285  int size() const
286  { return m_interface_vec.size(); }
287 
288 
289  // allow to call methods provided by the first interface
290  IF* operator -> ();
291  const IF* operator -> () const;
292 
293 
294  // allow to call methods provided by interface at index
295  inline const IF* get_interface( int iface_i ) const;
296  inline IF* get_interface( int iface_i );
297  IF* operator [] ( int index_ )
298  { return get_interface( index_ ); }
299  const IF* operator [] ( int index_ ) const
300  { return get_interface( index_ ); }
301 
302 
303  // get the first interface without checking for nil
304 
306  { return m_interface; }
307 
308  virtual const sc_interface* get_interface() const
309  { return m_interface; }
310 
311 protected:
312 
313  // constructors
314 
315  explicit sc_port_b( int max_size_,
317  base_type( max_size_, policy ), m_interface( 0 ), m_interface_vec()
318  {}
319 
320  sc_port_b( const char* name_, int max_size_,
322  base_type( name_, max_size_, policy ), m_interface( 0 ),
323  m_interface_vec()
324  {}
325 
326 
327  // destructor (does nothing)
328 
329  virtual ~sc_port_b()
330  {}
331 
332 
333  // called by pbind (for internal use only)
334  virtual int vbind( sc_interface& );
335  virtual int vbind( sc_port_base& );
336 
337 protected:
338 
339  // called by the sc_sensitive* classes
340  virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
341  virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
342 
343 private:
344 
345  // called by complete_binding (for internal use only)
346  virtual void add_interface( sc_interface* );
347  virtual const char* if_typename() const;
348  virtual int interface_count();
349 
350  // disabled
351  sc_port_b();
352  sc_port_b( const this_type& );
353  this_type& operator = ( const this_type& );
354 
355 private:
356 
357  IF* m_interface; // first interface in interface vec
358  std::vector<IF*> m_interface_vec;
359 };
360 
361 
362 // ----------------------------------------------------------------------------
363 // CLASS : sc_port
364 //
365 // Generic port class and base class for other port classes.
366 // N is the maximum number of channels (with interface IF) that can be bound
367 // to this port. N <= 0 means no maximum.
368 // ----------------------------------------------------------------------------
369 
370 extern void sc_warn_port_constructor();
371 
372 template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
373 class sc_port
374 : public sc_port_b<IF>
375 {
376  // typdefs
377 
378  typedef sc_port_b<IF> base_type;
379  typedef sc_port<IF,N,P> this_type;
380 
381 public:
382 
383  // constructors
384 
386  : base_type( N, P )
387  {}
388 
389  explicit sc_port( const char* name_ )
390  : base_type( name_, N, P )
391  {}
392 
393  explicit sc_port( IF& interface_ )
394  : base_type( N, P )
395  { sc_warn_port_constructor(); base_type::bind( interface_ ); }
396 
397  sc_port( const char* name_, IF& interface_ )
398  : base_type( name_, N, P )
399  { sc_warn_port_constructor(); base_type::bind( interface_ ); }
400 
401  explicit sc_port( base_type& parent_ )
402  : base_type( N, P )
403  { sc_warn_port_constructor(); base_type::bind( parent_ ); }
404 
405  sc_port( const char* name_, base_type& parent_ )
406  : base_type( name_, N, P )
407  { sc_warn_port_constructor(); base_type::bind( parent_ ); }
408 
409  sc_port( this_type& parent_ )
410  : base_type( N, P )
411  { sc_warn_port_constructor(); base_type::bind( parent_ ); }
412 
413  sc_port( const char* name_, this_type& parent_ )
414  : base_type( name_, N, P )
415  { sc_warn_port_constructor(); base_type::bind( parent_ ); }
416 
417 
418  // destructor (does nothing)
419 
420  virtual ~sc_port()
421  {}
422 
423  virtual const char* kind() const
424  { return "sc_port"; }
425 
426 private:
427 
428  // disabled
429  sc_port( const this_type& );
430  this_type& operator = ( const this_type& );
431 };
432 
433 
434 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
435 
436 // ----------------------------------------------------------------------------
437 // CLASS : sc_port_b
438 //
439 // Abstract base class for class sc_port.
440 // ----------------------------------------------------------------------------
441 
442 // allow to call methods provided by the first interface
443 
444 template <class IF>
445 inline
446 IF*
448 {
449  if( m_interface == 0 ) {
450  report_error( SC_ID_GET_IF_, "port is not bound" );
451  }
452  return m_interface;
453 }
454 
455 template <class IF>
456 inline
457 const IF*
459 {
460  if( m_interface == 0 ) {
461  report_error( SC_ID_GET_IF_, "port is not bound" );
462  }
463  return m_interface;
464 }
465 
466 
467 // allow to call methods provided by interface at index
468 //
469 // note that we special-case index of zero, since the method may be
470 // called before binding has occurred, and we need to return a zero
471 // in that case not an error.
472 
473 template <class IF>
474 inline
475 IF*
477 {
478  if ( index_ == 0 ) {
479  return m_interface;
480  }
481  else if( index_ < 0 || index_ >= size() ) {
482  report_error( SC_ID_GET_IF_, "index out of range" );
483  }
484  return m_interface_vec[index_];
485 }
486 
487 template <class IF>
488 inline
489 const IF*
490 sc_port_b<IF>::get_interface( int index_ ) const
491 {
492  if ( index_ == 0 ) {
493  return m_interface;
494  }
495  else if( index_ < 0 || index_ >= size() ) {
496  report_error( SC_ID_GET_IF_, "index out of range" );
497  }
498  return m_interface_vec[index_];
499 }
500 
501 
502 // called by pbind (for internal use only)
503 
504 template <class IF>
505 inline
506 int
508 {
509  IF* iface = DCAST<IF*>( &interface_ );
510  if( iface == 0 ) {
511  // type mismatch
512  return 2;
513  }
514  base_type::bind( *iface );
515  return 0;
516 }
517 
518 template <class IF>
519 inline
520 int
522 {
523  this_type* parent = DCAST<this_type*>( &parent_ );
524  if( parent == 0 ) {
525  // type mismatch
526  return 2;
527  }
528  base_type::bind( *parent );
529  return 0;
530 }
531 
532 
533 // called by complete_binding (for internal use only)
534 
535 template <class IF>
536 inline
537 void
539 {
540  IF* iface = DCAST<IF*>( interface_ );
541  assert( iface != 0 );
542 
543  // make sure that the interface is not already bound:
544 
545  int size = m_interface_vec.size();
546  for ( int i = 0; i < size; i++ )
547  {
548  if ( iface == m_interface_vec[i] )
549  {
550  report_error( SC_ID_BIND_IF_TO_PORT_,
551  "interface already bound to port" );
552  }
553  }
554 
555  // "bind" the interface and make sure our short cut for 0 is set up.
556 
557  m_interface_vec.push_back( iface );
558  m_interface = m_interface_vec[0];
559 }
560 
561 template <class IF>
562 inline
563 const char*
564 sc_port_b<IF>::if_typename() const
565 {
566  return typeid( IF ).name();
567 }
568 
569 template <class IF>
570 inline
571 int
572 sc_port_b<IF>::interface_count()
573 {
574  return m_interface_vec.size();
575 }
576 
577 template <class IF>
578 void
580  sc_event_finder* event_finder_ ) const
581 {
582  if ( m_bind_info == 0 )
583  {
584  int if_n = m_interface_vec.size();
585  for ( int if_i = 0; if_i < if_n; if_i++ )
586  {
587  IF* iface_p = m_interface_vec[if_i];
588  assert( iface_p != 0 );
589  add_static_event( handle_p, iface_p->default_event() );
590  }
591  }
592  else
593  {
594  sc_port_base::make_sensitive( handle_p, event_finder_ );
595  }
596 }
597 
598 template <class IF>
599 void
601  sc_event_finder* event_finder_ ) const
602 {
603  if ( m_bind_info == 0 )
604  {
605  int if_n = m_interface_vec.size();
606  for ( int if_i = 0; if_i < if_n; if_i++ )
607  {
608  IF* iface_p = m_interface_vec[if_i];
609  assert( iface_p != 0 );
610  add_static_event( handle_p, iface_p->default_event() );
611  }
612  }
613  else
614  {
615  sc_port_base::make_sensitive( handle_p, event_finder_ );
616  }
617 }
618 
619 // ----------------------------------------------------------------------------
620 // CLASS : sc_port
621 //
622 // Generic port class and base class for other port classes.
623 // N is the maximum number of channels (with interface IF) that can be bound
624 // to this port. N <= 0 means no maximum.
625 // ----------------------------------------------------------------------------
626 
627 } // namespace sc_core
628 
629 #undef SC_VIRTUAL_
630 
631 /*****************************************************************************
632 
633  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
634  changes you are making here.
635 
636  Name, Affiliation, Date: Andy Goodrich, Forte,
637  Bishnupriya Bhattacharya, Cadence Design Systems,
638  25 August, 2003
639  Description of Modification: phase callbacks
640 
641  Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
642  12 December, 2005
643  Description of Modification: multiport binding policy changes
644 
645 
646  *****************************************************************************/
647 
648 /*
649 $Log: sc_port.h,v $
650 Revision 1.10 2011/08/26 20:45:41 acg
651  Andy Goodrich: moved the modification log to the end of the file to
652  eliminate source line number skew when check-ins are done.
653 
654 Revision 1.9 2011/08/24 22:05:36 acg
655  Torsten Maehne: initialization changes to remove warnings.
656 
657 Revision 1.8 2011/08/07 19:08:01 acg
658  Andy Goodrich: moved logs to end of file so line number synching works
659  better between versions.
660 
661 Revision 1.7 2011/08/07 18:53:09 acg
662  Philipp A. Hartmann: add virtual instances of the bind function for
663  base classes to eliminate warning messages for clang platforms.
664 
665 Revision 1.6 2011/05/09 04:07:37 acg
666  Philipp A. Hartmann:
667  (1) Restore hierarchy in all phase callbacks.
668  (2) Ensure calls to before_end_of_elaboration.
669 
670 Revision 1.5 2011/03/30 16:46:10 acg
671  Andy Goodrich: added a signature and removed a virtual specification
672  to eliminate warnings with certain compilers.
673 
674 Revision 1.4 2011/02/18 20:23:45 acg
675  Andy Goodrich: Copyright update.
676 
677 Revision 1.3 2011/01/20 16:52:15 acg
678  Andy Goodrich: changes for IEEE 1666 2011.
679 
680 Revision 1.2 2010/08/03 18:01:11 acg
681  Andy Goodrich: formatting.
682 
683 Revision 1.1.1.1 2006/12/15 20:20:04 acg
684 SystemC 2.3
685 
686 Revision 1.5 2006/08/29 23:35:00 acg
687  Andy Goodrich: added bind_count() method to allow users to determine which
688  ports are connected in before_end_of_elaboration().
689 
690 Revision 1.4 2006/05/08 17:52:47 acg
691  Andy Goodrich:
692  (1) added David Long's forward declarations for friend functions,
693  methods, and operators to keep the Microsoft compiler happy.
694  (2) Added delta_count() method to sc_prim_channel for use by
695  sc_signal so that the friend declaration in sc_simcontext.h
696  can be for a non-templated class (i.e., sc_prim_channel.)
697 
698 Revision 1.3 2006/01/24 20:46:31 acg
699 Andy Goodrich: changes to eliminate use of deprecated features. For instance,
700 using notify(SC_ZERO_TIME) in place of notify_delayed().
701 
702 Revision 1.2 2006/01/03 23:18:26 acg
703 Changed copyright to include 2006.
704 
705 Revision 1.1.1.1 2005/12/19 23:16:43 acg
706 First check in of SystemC 2.1 into its own archive.
707 
708 Revision 1.10 2005/09/15 23:01:51 acg
709 Added std:: prefix to appropriate methods and types to get around
710 issues with the Edison Front End.
711 
712 Revision 1.9 2005/08/10 01:35:59 acg
713 Changes for 64-bit support.
714 
715 Revision 1.8 2005/04/03 22:52:51 acg
716 Namespace changes.
717 
718 Revision 1.7 2005/03/21 22:31:32 acg
719 Changes to sc_core namespace.
720 
721 Revision 1.6 2004/09/27 21:02:54 acg
722 Andy Goodrich - Forte Design Systems, Inc.
723  - Added a $Log comment so that CVS checkin comments will appear in
724  checked out source.
725 
726 */
727 
728 #endif
729 
730 // Taf!
virtual sc_interface * get_interface()=0
virtual const char * kind() const
Definition: sc_port.h:423
virtual void start_of_simulation()
virtual void before_end_of_elaboration()
this_type port_type
Definition: sc_port.h:261
#define SC_VIRTUAL_
Definition: sc_port.h:39
virtual sc_interface * get_interface()
Definition: sc_port.h:305
sc_bind_info * m_bind_info
Definition: sc_port.h:171
sc_port(IF &interface_)
Definition: sc_port.h:393
virtual void end_of_elaboration()
virtual ~sc_port()
Definition: sc_port.h:420
sc_port_policy
Definition: sc_port.h:50
virtual int interface_count()=0
int size() const
Definition: sc_port.h:285
void operator()(IF &interface_)
Definition: sc_port.h:270
sc_port(this_type &parent_)
Definition: sc_port.h:409
IF * operator->()
Definition: sc_port.h:447
sc_port_base base_type
Definition: sc_port.h:259
void report_error(const char *id, const char *add_msg=0) const
SC_VIRTUAL_ void bind(IF &interface_)
Definition: sc_port.h:267
sc_port_base this_type
Definition: sc_port.h:82
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:58
virtual int vbind(sc_interface &)=0
sc_port_b< IF > this_type
Definition: sc_port.h:260
SC_VIRTUAL_ void bind(port_type &parent_)
Definition: sc_port.h:276
sc_port_b(const char *name_, int max_size_, sc_port_policy policy=SC_ONE_OR_MORE_BOUND)
Definition: sc_port.h:320
sc_port(const char *name_, this_type &parent_)
Definition: sc_port.h:413
void add_static_event(sc_method_handle process_p, const sc_event &event) const
sc_port_b(int max_size_, sc_port_policy policy=SC_ONE_OR_MORE_BOUND)
Definition: sc_port.h:315
void sc_warn_port_constructor()
sc_port(const char *name_, base_type &parent_)
Definition: sc_port.h:405
sc_port(const char *name_, IF &interface_)
Definition: sc_port.h:397
virtual ~sc_port_b()
Definition: sc_port.h:329
virtual const sc_interface * get_interface() const
Definition: sc_port.h:308
virtual const char * if_typename() const =0
virtual void make_sensitive(sc_thread_handle, sc_event_finder *=0) const
Definition: sc_port.h:579
virtual const char * kind() const
Definition: sc_port.h:92
sc_port(base_type &parent_)
Definition: sc_port.h:401
virtual void add_interface(sc_interface *)=0
virtual void make_sensitive(sc_thread_handle, sc_event_finder *=0) const
void insert(sc_port_base *)
IF * operator[](int index_)
Definition: sc_port.h:297
class sc_method_process * sc_method_handle
Definition: sc_process.h:57
virtual void end_of_simulation()
sc_port(const char *name_)
Definition: sc_port.h:389
void bind(sc_interface &interface_)
virtual int vbind(sc_interface &)
Definition: sc_port.h:507