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