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