SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_signal_ports.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_signal_ports.h -- The sc_signal<T> port classes.
21 
22  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
23 
24  CHANGE LOG APPEARS AT THE END OF THE FILE
25  *****************************************************************************/
26 
27 #ifndef SC_SIGNAL_PORTS_H
28 #define SC_SIGNAL_PORTS_H
29 
30 
35 #include "sysc/tracing/sc_trace.h"
36 
37 #if ! defined( SC_DISABLE_VIRTUAL_BIND )
38 # define SC_VIRTUAL_ virtual
39 #else
40 # define SC_VIRTUAL_ /* non-virtual */
41 #endif
42 
43 namespace sc_core {
44 
45 // ----------------------------------------------------------------------------
46 // STRUCT : sc_trace_params
47 //
48 // Struct for storing the trace file and object name of an sc_trace call.
49 // FOR INTERNAL USE ONLY!
50 // ----------------------------------------------------------------------------
51 
52 extern void sc_deprecated_add_trace();
53 
55 {
57  std::string name;
58 
59  sc_trace_params( sc_trace_file* tf_, const std::string& name_ )
60  : tf( tf_ ), name( name_ )
61  {}
62 };
63 
64 
65 typedef std::vector<sc_trace_params*> sc_trace_params_vec;
66 
67 
68 // ----------------------------------------------------------------------------
69 // CLASS : sc_in<T>
70 //
71 // The sc_signal<T> input port class.
72 // ----------------------------------------------------------------------------
73 
74 template <class T>
75 class sc_in
76 : public sc_port<sc_signal_in_if<T>,1,SC_ONE_OR_MORE_BOUND>
77 {
78 public:
79 
80  // typedefs
81 
82  typedef T data_type;
83 
88 
93 
94 public:
95 
96  // constructors
97 
99  : base_type(), m_traces( 0 ),
100  m_change_finder_p(0)
101  {}
102 
103  explicit sc_in( const char* name_ )
104  : base_type( name_ ), m_traces( 0 ),
105  m_change_finder_p(0)
106  {}
107 
108  explicit sc_in( const in_if_type& interface_ )
109  : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
110  m_change_finder_p(0)
111  {}
112 
113  sc_in( const char* name_, const in_if_type& interface_ )
114  : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
115  m_change_finder_p(0)
116  {}
117 
118  explicit sc_in( in_port_type& parent_ )
119  : base_type( parent_ ), m_traces( 0 ),
120  m_change_finder_p(0)
121  {}
122 
123  sc_in( const char* name_, in_port_type& parent_ )
124  : base_type( name_, parent_ ), m_traces( 0 ),
125  m_change_finder_p(0)
126  {}
127 
128  explicit sc_in( inout_port_type& parent_ )
129  : base_type(), m_traces( 0 ),
130  m_change_finder_p(0)
131  { sc_port_base::bind( parent_ ); }
132 
133  sc_in( const char* name_, inout_port_type& parent_ )
134  : base_type( name_ ), m_traces( 0 ),
135  m_change_finder_p(0)
136  { sc_port_base::bind( parent_ ); }
137 
138  sc_in( this_type& parent_ )
139  : base_type( parent_ ), m_traces( 0 ),
140  m_change_finder_p(0)
141  {}
142 
143  sc_in( const char* name_, this_type& parent_ )
144  : base_type( name_, parent_ ), m_traces( 0 ),
145  m_change_finder_p(0)
146  {}
147 
148 
149  // destructor
150 
151  virtual ~sc_in()
152  {
153  remove_traces();
154  delete m_change_finder_p;
155  }
156 
157 
158  // bind to in interface
159 
160  SC_VIRTUAL_ void bind( const in_if_type& interface_ )
161  { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
162 
163  SC_VIRTUAL_ void bind( in_if_type& interface_ )
164  { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
165 
166  void operator () ( const in_if_type& interface_ )
167  { this->bind( interface_ ); }
168 
169 
170  // bind to parent in port
171 
172  SC_VIRTUAL_ void bind( in_port_type& parent_ )
173  { sc_port_base::bind( parent_ ); }
174 
175  void operator () ( in_port_type& parent_ )
176  { this->bind( parent_ ); }
177 
178 
179  // bind to parent inout port
180 
182  { sc_port_base::bind( parent_ ); }
183 
184  void operator () ( inout_port_type& parent_ )
185  { this->bind( parent_ ); }
186 
187 
188  // interface access shortcut methods
189 
190  // get the default event
191 
192  const sc_event& default_event() const
193  { return (*this)->default_event(); }
194 
195 
196  // get the value changed event
197 
199  { return (*this)->value_changed_event(); }
200 
201 
202  // read the current value
203 
204  const data_type& read() const
205  { return (*this)->read(); }
206 
207  operator const data_type& () const
208  { return (*this)->read(); }
209 
210 
211  // was there a value changed event?
212 
213  bool event() const
214  { return (*this)->event(); }
215 
216 
217  // (other) event finder method(s)
218 
220  {
221  if ( !m_change_finder_p )
222  {
223  m_change_finder_p = new sc_event_finder_t<in_if_type>(
225  }
226  return *m_change_finder_p;
227  }
228 
229 
230  // called when elaboration is done
231  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
232  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
233 
234  virtual void end_of_elaboration();
235 
236  virtual const char* kind() const
237  { return "sc_in"; }
238 
239 
240  void add_trace( sc_trace_file*, const std::string& ) const;
241 
242  // called by sc_trace
243  void add_trace_internal( sc_trace_file*, const std::string& ) const;
244 
245 protected:
246 
247  void remove_traces() const;
248 
250 
251 protected:
252 
253  // called by pbind (for internal use only)
254  virtual int vbind( sc_interface& );
255  virtual int vbind( sc_port_base& );
256 
257  // implement virtual base_type port-binding function
258  // - avoids warnings on some compilers
259  // - should only be called, when using sc_port_b explicitly
260  // - errors are detected during elaboration
261 
262  SC_VIRTUAL_ void bind( base_port_type& parent_ )
263  { sc_port_base::bind( parent_ ); }
264 
265 
266 private:
267  mutable sc_event_finder* m_change_finder_p;
268 
269 private:
270 
271  // disabled
272  sc_in( const this_type& );
273  this_type& operator = ( const this_type& );
274 
275 #ifdef __GNUC__
276  // Needed to circumvent a problem in the g++-2.95.2 compiler:
277  // This unused variable forces the compiler to instantiate
278  // an object of T template so an implicit conversion from
279  // read() to a C++ intrinsic data type will work.
280  static data_type dummy;
281 #endif
282 };
283 
284 template<typename T>
285 ::std::ostream& operator << ( ::std::ostream& os, const sc_in<T>& a )
286 {
287  return os << a->read();
288 }
289 
290 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
291 
292 
293 // called when elaboration is done
294 
295 template <class T>
296 inline
297 void
299 {
300  if( m_traces != 0 ) {
301  for( int i = 0; i < (int)m_traces->size(); ++ i ) {
302  sc_trace_params* p = (*m_traces)[i];
303  in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
304  sc_trace( p->tf, iface->read(), p->name );
305  }
306  remove_traces();
307  }
308 }
309 
310 
311 // called by sc_trace
312 
313 template <class T>
314 inline
315 void
316 sc_in<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_ )
317 const
318 {
319  if( tf_ != 0 ) {
320  if( m_traces == 0 ) {
321  m_traces = new sc_trace_params_vec;
322  }
323  m_traces->push_back( new sc_trace_params( tf_, name_ ) );
324  }
325 }
326 
327 template <class T>
328 inline
329 void
330 sc_in<T>::add_trace( sc_trace_file* tf_, const std::string& name_ )
331 const
332 {
334  add_trace_internal(tf_, name_);
335 }
336 
337 template <class T>
338 inline
339 void
341 {
342  if( m_traces != 0 ) {
343  for( int i = (int)m_traces->size() - 1; i >= 0; -- i ) {
344  delete (*m_traces)[i];
345  }
346  delete m_traces;
347  m_traces = 0;
348  }
349 }
350 
351 
352 // called by pbind (for internal use only)
353 
354 template <class T>
355 inline
356 int
358 {
359  return sc_port_b<if_type>::vbind( interface_ );
360 }
361 
362 template <class T>
363 inline
364 int
366 {
367  in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
368  if( in_parent != 0 ) {
369  sc_port_base::bind( *in_parent );
370  return 0;
371  }
372  inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
373  if( inout_parent != 0 ) {
374  sc_port_base::bind( *inout_parent );
375  return 0;
376  }
377  // type mismatch
378  return 2;
379 }
380 
381 
382 // ----------------------------------------------------------------------------
383 // CLASS : sc_in<bool>
384 //
385 // Specialization of sc_in<T> for type bool.
386 // ----------------------------------------------------------------------------
387 
388 template <>
389 class sc_in<bool> :
390  public sc_port<sc_signal_in_if<bool>,1,SC_ONE_OR_MORE_BOUND>
391 {
392 public:
393 
394  // typedefs
395 
396  typedef bool data_type;
397 
401  typedef /* typename */ base_type::port_type base_port_type;
402 
407 
408 public:
409 
410  // constructors
411 
413  : base_type(), m_traces( 0 ), m_change_finder_p(0),
414  m_neg_finder_p(0), m_pos_finder_p(0)
415  {}
416 
417  explicit sc_in( const char* name_ )
418  : base_type( name_ ), m_traces( 0 ), m_change_finder_p(0),
419  m_neg_finder_p(0), m_pos_finder_p(0)
420  {}
421 
422  explicit sc_in( const in_if_type& interface_ )
423  : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
424  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
425  {}
426 
427  sc_in( const char* name_, const in_if_type& interface_ )
428  : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
429  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
430  {}
431 
432  explicit sc_in( in_port_type& parent_ )
433  : base_type( parent_ ), m_traces( 0 ),
434  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
435  {}
436 
437  sc_in( const char* name_, in_port_type& parent_ )
438  : base_type( name_, parent_ ), m_traces( 0 ),
439  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
440  {}
441 
442  explicit sc_in( inout_port_type& parent_ )
443  : base_type(), m_traces( 0 ),
444  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
445  { sc_port_base::bind( parent_ ); }
446 
447  sc_in( const char* name_, inout_port_type& parent_ )
448  : base_type( name_ ), m_traces( 0 ),
449  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
450  { sc_port_base::bind( parent_ ); }
451 
452  sc_in( this_type& parent_ )
453  : base_type( parent_ ), m_traces( 0 ),
454  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
455  {}
456 
457 #if defined(TESTING)
458  sc_in( const this_type& parent_ )
459  : base_type( *(in_if_type*)parent_.get_interface() ) , m_traces( 0 ),
460  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
461  {}
462 #endif
463 
464  sc_in( const char* name_, this_type& parent_ )
465  : base_type( name_, parent_ ), m_traces( 0 ),
466  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
467  {}
468 
469 
470  // destructor
471 
472  virtual ~sc_in()
473  {
474  remove_traces();
475  delete m_change_finder_p;
476  delete m_neg_finder_p;
477  delete m_pos_finder_p;
478  }
479 
480 
481  // bind to in interface
482 
483  SC_VIRTUAL_ void bind( const in_if_type& interface_ )
484  { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
485 
486  SC_VIRTUAL_ void bind( in_if_type& interface_ )
487  { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
488 
489  void operator () ( const in_if_type& interface_ )
490  { this->bind( interface_ ); }
491 
492 
493  // bind to parent in port
494 
495  SC_VIRTUAL_ void bind( in_port_type& parent_ )
496  { sc_port_base::bind( parent_ ); }
497 
498  void operator () ( in_port_type& parent_ )
499  { this->bind( parent_ ); }
500 
501 
502  // bind to parent inout port
503 
505  { sc_port_base::bind( parent_ ); }
506 
507  void operator () ( inout_port_type& parent_ )
508  { this->bind( parent_ ); }
509 
510 
511  // interface access shortcut methods
512 
513  // get the default event
514 
515  const sc_event& default_event() const
516  { return (*this)->default_event(); }
517 
518 
519  // get the value changed event
520 
522  { return (*this)->value_changed_event(); }
523 
524  // get the positive edge event
525 
526  const sc_event& posedge_event() const
527  { return (*this)->posedge_event(); }
528 
529  // get the negative edge event
530 
531  const sc_event& negedge_event() const
532  { return (*this)->negedge_event(); }
533 
534 
535  // read the current value
536 
537  const data_type& read() const
538  { return (*this)->read(); }
539 
540  operator const data_type& () const
541  { return (*this)->read(); }
542 
543 
544  // use for positive edge sensitivity
545 
547  {
548  if ( !m_pos_finder_p )
549  {
550  m_pos_finder_p = new sc_event_finder_t<in_if_type>(
551  *this, &in_if_type::posedge_event );
552  }
553  return *m_pos_finder_p;
554  }
555 
556  // use for negative edge sensitivity
557 
559  {
560  if ( !m_neg_finder_p )
561  {
562  m_neg_finder_p = new sc_event_finder_t<in_if_type>(
563  *this, &in_if_type::negedge_event );
564  }
565  return *m_neg_finder_p;
566  }
567 
568 
569  // was there a value changed event?
570 
571  bool event() const
572  { return (*this)->event(); }
573 
574  // was there a positive edge event?
575 
576  bool posedge() const
577  { return (*this)->posedge(); }
578 
579  // was there a negative edge event?
580 
581  bool negedge() const
582  { return (*this)->negedge(); }
583 
584  // (other) event finder method(s)
585 
587  {
588  if ( !m_change_finder_p )
589  {
590  m_change_finder_p = new sc_event_finder_t<in_if_type>(
592  }
593  return *m_change_finder_p;
594  }
595 
596 
597  // called when elaboration is done
598  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
599  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
600 
601  virtual void end_of_elaboration();
602 
603  virtual const char* kind() const
604  { return "sc_in"; }
605 
606 
607  void add_trace( sc_trace_file*, const std::string& ) const;
608 
609  // called by sc_trace
610  void add_trace_internal( sc_trace_file*, const std::string& ) const;
611 
612 protected:
613 
614  void remove_traces() const;
615 
617 
618 protected:
619 
620  // called by pbind (for internal use only)
621  virtual int vbind( sc_interface& );
622  virtual int vbind( sc_port_base& );
623 
624  // implement virtual base_type port-binding function
625  // - avoids warnings on some compilers
626  // - should only be called, when using sc_port_b explicitly
627  // - errors are detected during elaboration
628 
629  SC_VIRTUAL_ void bind( base_port_type& parent_ )
630  { sc_port_base::bind( parent_ ); }
631 
632 private:
633  mutable sc_event_finder* m_change_finder_p;
634  mutable sc_event_finder* m_neg_finder_p;
635  mutable sc_event_finder* m_pos_finder_p;
636 
637 private:
638 
639  // disabled
640 #if defined(TESTING)
641 #else
642  sc_in( const this_type& );
643 #endif
644  this_type& operator = ( const this_type& );
645 
646 #ifdef __GNUC__
647  // Needed to circumvent a problem in the g++-2.95.2 compiler:
648  // This unused variable forces the compiler to instantiate
649  // an object of T template so an implicit conversion from
650  // read() to a C++ intrinsic data type will work.
651  static data_type dummy;
652 #endif
653 };
654 
655 
656 // ----------------------------------------------------------------------------
657 // CLASS : sc_in<sc_dt::sc_logic>
658 //
659 // Specialization of sc_in<T> for type sc_dt::sc_logic.
660 // ----------------------------------------------------------------------------
661 
662 template <>
663 class sc_in<sc_dt::sc_logic>
664 : public sc_port<sc_signal_in_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
665 {
666 public:
667 
668  // typedefs
669 
671 
675  typedef /* typename */ base_type::port_type base_port_type;
676 
681 
682 public:
683 
684  // constructors
685 
687  : base_type(), m_traces( 0 ),
688  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
689  {}
690 
691  explicit sc_in( const char* name_ )
692  : base_type( name_ ), m_traces( 0 ),
693  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
694  {}
695 
696  explicit sc_in( const in_if_type& interface_ )
697  : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
698  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
699  {}
700 
701  sc_in( const char* name_, const in_if_type& interface_ )
702  : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
703  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
704  {}
705 
706  explicit sc_in( in_port_type& parent_ )
707  : base_type( parent_ ), m_traces( 0 ),
708  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
709  {}
710 
711  sc_in( const char* name_, in_port_type& parent_ )
712  : base_type( name_, parent_ ), m_traces( 0 ),
713  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
714  {}
715 
716  explicit sc_in( inout_port_type& parent_ )
717  : base_type(), m_traces( 0 ),
718  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
719  { sc_port_base::bind( parent_ ); }
720 
721  sc_in( const char* name_, inout_port_type& parent_ )
722  : base_type( name_ ), m_traces( 0 ),
723  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
724  { sc_port_base::bind( parent_ ); }
725 
726  sc_in( this_type& parent_ )
727  : base_type( parent_ ), m_traces( 0 ),
728  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
729  {}
730 
731  sc_in( const char* name_, this_type& parent_ )
732  : base_type( name_, parent_ ), m_traces( 0 ),
733  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
734  {}
735 
736 
737  // destructor
738 
739  virtual ~sc_in()
740  {
741  remove_traces();
742  delete m_change_finder_p;
743  delete m_neg_finder_p;
744  delete m_pos_finder_p;
745  }
746 
747 
748  // bind to in interface
749 
750  SC_VIRTUAL_ void bind( const in_if_type& interface_ )
751  { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
752 
753  SC_VIRTUAL_ void bind( in_if_type& interface_ )
754  { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
755 
756  void operator () ( const in_if_type& interface_ )
757  { this->bind( interface_ ); }
758 
759 
760  // bind to parent in port
761 
762  SC_VIRTUAL_ void bind( in_port_type& parent_ )
763  { sc_port_base::bind( parent_ ); }
764 
765  void operator () ( in_port_type& parent_ )
766  { this->bind( parent_ ); }
767 
768 
769  // bind to parent inout port
770 
772  { sc_port_base::bind( parent_ ); }
773 
774  void operator () ( inout_port_type& parent_ )
775  { this->bind( parent_ ); }
776 
777 
778  // interface access shortcut methods
779 
780  // get the default event
781 
782  const sc_event& default_event() const
783  { return (*this)->default_event(); }
784 
785 
786  // get the value changed event
787 
789  { return (*this)->value_changed_event(); }
790 
791  // get the positive edge event
792 
793  const sc_event& posedge_event() const
794  { return (*this)->posedge_event(); }
795 
796  // get the negative edge event
797 
798  const sc_event& negedge_event() const
799  { return (*this)->negedge_event(); }
800 
801 
802  // read the current value
803 
804  const data_type& read() const
805  { return (*this)->read(); }
806 
807  operator const data_type& () const
808  { return (*this)->read(); }
809 
810 
811  // use for positive edge sensitivity
812 
814  {
815  if ( !m_pos_finder_p )
816  {
817  m_pos_finder_p = new sc_event_finder_t<in_if_type>(
818  *this, &in_if_type::posedge_event );
819  }
820  return *m_pos_finder_p;
821  }
822 
823  // use for negative edge sensitivity
824 
826  {
827  if ( !m_neg_finder_p )
828  {
829  m_neg_finder_p = new sc_event_finder_t<in_if_type>(
830  *this, &in_if_type::negedge_event );
831  }
832  return *m_neg_finder_p;
833  }
834 
835 
836  // was there a value changed event?
837 
838  bool event() const
839  { return (*this)->event(); }
840 
841  // was there a positive edge event?
842 
843  bool posedge() const
844  { return (*this)->posedge(); }
845 
846  // was there a negative edge event?
847 
848  bool negedge() const
849  { return (*this)->negedge(); }
850 
851  // (other) event finder method(s)
852 
854  {
855  if ( !m_change_finder_p )
856  {
857  m_change_finder_p = new sc_event_finder_t<in_if_type>(
859  }
860  return *m_change_finder_p;
861  }
862 
863 
864  // called when elaboration is done
865  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
866  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
867 
868  virtual void end_of_elaboration();
869 
870  virtual const char* kind() const
871  { return "sc_in"; }
872 
873 
874  void add_trace( sc_trace_file*, const std::string& ) const;
875 
876  // called by sc_trace
877  void add_trace_internal( sc_trace_file*, const std::string& ) const;
878 
879 protected:
880 
881  void remove_traces() const;
882 
884 
885 protected:
886 
887  // called by pbind (for internal use only)
888  virtual int vbind( sc_interface& );
889  virtual int vbind( sc_port_base& );
890 
891  // implement virtual base_type port-binding function
892  // - avoids warnings on some compilers
893  // - should only be called, when using sc_port_b explicitly
894  // - errors are detected during elaboration
895 
896  SC_VIRTUAL_ void bind( base_port_type& parent_ )
897  { sc_port_base::bind( parent_ ); }
898 
899 private:
900  mutable sc_event_finder* m_change_finder_p;
901  mutable sc_event_finder* m_neg_finder_p;
902  mutable sc_event_finder* m_pos_finder_p;
903 
904 private:
905 
906  // disabled
907  sc_in( const this_type& );
908  this_type& operator = ( const this_type& );
909 
910 #ifdef __GNUC__
911  // Needed to circumvent a problem in the g++-2.95.2 compiler:
912  // This unused variable forces the compiler to instantiate
913  // an object of T template so an implicit conversion from
914  // read() to a C++ intrinsic data type will work.
915  static data_type dummy;
916 #endif
917 };
918 
919 
920 // ----------------------------------------------------------------------------
921 // CLASS : sc_inout<T>
922 //
923 // The sc_signal<T> input/output port class.
924 // ----------------------------------------------------------------------------
925 
926 template <class T>
927 class sc_inout
928 : public sc_port<sc_signal_inout_if<T>,1,SC_ONE_OR_MORE_BOUND>
929 {
930 public:
931 
932  // typedefs
933 
934  typedef T data_type;
935 
939 
944 
945 public:
946 
947  // constructors
948 
950  : base_type(), m_init_val( 0 ), m_traces( 0 ),
951  m_change_finder_p(0)
952  {}
953 
954  explicit sc_inout( const char* name_ )
955  : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
956  m_change_finder_p(0)
957  {}
958 
959  explicit sc_inout( inout_if_type& interface_ )
960  : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
961  m_change_finder_p(0)
962  {}
963 
964  sc_inout( const char* name_, inout_if_type& interface_ )
965  : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
966  m_change_finder_p(0)
967  {}
968 
969  explicit sc_inout( inout_port_type& parent_ )
970  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
971  m_change_finder_p(0)
972  {}
973 
974  sc_inout( const char* name_, inout_port_type& parent_ )
975  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
976  m_change_finder_p(0)
977  {}
978 
979  sc_inout( this_type& parent_ )
980  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
981  m_change_finder_p(0)
982  {}
983 
984  sc_inout( const char* name_, this_type& parent_ )
985  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
986  m_change_finder_p(0)
987  {}
988 
989 
990  // destructor
991 
992  virtual ~sc_inout();
993 
994 
995  // interface access shortcut methods
996 
997  // get the default event
998 
999  const sc_event& default_event() const
1000  { return (*this)->default_event(); }
1001 
1002 
1003  // get the value changed event
1004 
1006  { return (*this)->value_changed_event(); }
1007 
1008 
1009  // read the current value
1010 
1011  const data_type& read() const
1012  { return (*this)->read(); }
1013 
1014  operator const data_type& () const
1015  { return (*this)->read(); }
1016 
1017 
1018  // was there a value changed event?
1019 
1020  bool event() const
1021  { return (*this)->event(); }
1022 
1023 
1024  // write the new value
1025 
1026  void write( const data_type& value_ )
1027  { (*this)->write( value_ ); }
1028 
1029  this_type& operator = ( const data_type& value_ )
1030  { (*this)->write( value_ ); return *this; }
1031 
1032  this_type& operator = ( const in_if_type& interface_ )
1033  { (*this)->write( interface_.read() ); return *this; }
1034 
1036  { (*this)->write( port_->read() ); return *this; }
1037 
1039  { (*this)->write( port_->read() ); return *this; }
1040 
1042  { (*this)->write( port_->read() ); return *this; }
1043 
1044 
1045  // set initial value (can also be called when port is not bound yet)
1046 
1047  void initialize( const data_type& value_ );
1048 
1049  void initialize( const in_if_type& interface_ )
1050  { initialize( interface_.read() ); }
1051 
1052 
1053  // called when elaboration is done
1054  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
1055  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
1056 
1057  virtual void end_of_elaboration();
1058 
1059 
1060  // (other) event finder method(s)
1061 
1063  {
1064  if ( !m_change_finder_p )
1065  {
1066  m_change_finder_p = new sc_event_finder_t<in_if_type>(
1068  }
1069  return *m_change_finder_p;
1070  }
1071 
1072  virtual const char* kind() const
1073  { return "sc_inout"; }
1074 
1075 protected:
1076 
1078 
1079 public:
1080 
1081  // called by sc_trace
1082  void add_trace_internal( sc_trace_file*, const std::string& ) const;
1083 
1084  void add_trace( sc_trace_file*, const std::string& ) const;
1085 
1086 protected:
1087 
1088  void remove_traces() const;
1089 
1091 
1092 private:
1093  mutable sc_event_finder* m_change_finder_p;
1094 
1095 private:
1096 
1097  // disabled
1098  sc_inout( const this_type& );
1099 
1100 #ifdef __GNUC__
1101  // Needed to circumvent a problem in the g++-2.95.2 compiler:
1102  // This unused variable forces the compiler to instantiate
1103  // an object of T template so an implicit conversion from
1104  // read() to a C++ intrinsic data type will work.
1105  static data_type dummy;
1106 #endif
1107 };
1108 
1109 template<typename T>
1110 ::std::ostream& operator << ( ::std::ostream& os, const sc_inout<T>& a )
1111 {
1112  return os << a->read();
1113 }
1114 
1115 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1116 
1117 
1118 // destructor
1119 
1120 template <class T>
1121 inline
1123 {
1124  delete m_change_finder_p;
1125  delete m_init_val;
1126  remove_traces();
1127 }
1128 
1129 
1130 // set initial value (can also be called when port is not bound yet)
1131 
1132 template <class T>
1133 inline
1134 void
1136 {
1137  inout_if_type* iface = DCAST<inout_if_type*>( this->get_interface() );
1138  if( iface != 0 ) {
1139  iface->write( value_ );
1140  } else {
1141  if( m_init_val == 0 ) {
1142  m_init_val = new data_type;
1143  }
1144  *m_init_val = value_;
1145  }
1146 }
1147 
1148 
1149 // called when elaboration is done
1150 
1151 template <class T>
1152 inline
1153 void
1155 {
1156  if( m_init_val != 0 ) {
1157  write( *m_init_val );
1158  delete m_init_val;
1159  m_init_val = 0;
1160  }
1161  if( m_traces != 0 ) {
1162  for( int i = 0; i < (int)m_traces->size(); ++ i ) {
1163  sc_trace_params* p = (*m_traces)[i];
1164  in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
1165  sc_trace( p->tf, iface->read(), p->name );
1166  }
1167  remove_traces();
1168  }
1169 }
1170 
1171 
1172 // called by sc_trace
1173 
1174 template <class T>
1175 inline
1176 void
1177 sc_inout<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_)
1178 const
1179 {
1180  if( tf_ != 0 ) {
1181  if( m_traces == 0 ) {
1182  m_traces = new sc_trace_params_vec;
1183  }
1184  m_traces->push_back( new sc_trace_params( tf_, name_ ) );
1185  }
1186 }
1187 
1188 template <class T>
1189 inline
1190 void
1191 sc_inout<T>::add_trace( sc_trace_file* tf_, const std::string& name_) const
1192 {
1194  add_trace_internal(tf_, name_);
1195 }
1196 
1197 template <class T>
1198 inline
1199 void
1201 {
1202  if( m_traces != 0 ) {
1203  for( int i = m_traces->size() - 1; i >= 0; -- i ) {
1204  delete (*m_traces)[i];
1205  }
1206  delete m_traces;
1207  m_traces = 0;
1208  }
1209 }
1210 
1211 
1212 // ----------------------------------------------------------------------------
1213 // CLASS : sc_inout<bool>
1214 //
1215 // Specialization of sc_inout<T> for type bool.
1216 // ----------------------------------------------------------------------------
1217 
1218 template <>
1219 class sc_inout<bool> :
1220  public sc_port<sc_signal_inout_if<bool>,1,SC_ONE_OR_MORE_BOUND>
1221 {
1222 public:
1223 
1224  // typedefs
1225 
1226  typedef bool data_type;
1227 
1231 
1236 
1237 public:
1238 
1239  // constructors
1240 
1242  : base_type(), m_init_val( 0 ), m_traces( 0 ),
1243  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1244  {}
1245 
1246  explicit sc_inout( const char* name_ )
1247  : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
1248  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1249  {}
1250 
1251  explicit sc_inout( inout_if_type& interface_ )
1252  : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
1253  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1254  {}
1255 
1256  sc_inout( const char* name_, inout_if_type& interface_ )
1257  : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
1258  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1259  {}
1260 
1261  explicit sc_inout( inout_port_type& parent_ )
1262  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
1263  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1264  {}
1265 
1266  sc_inout( const char* name_, inout_port_type& parent_ )
1267  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
1268  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1269  {}
1270 
1271  sc_inout( this_type& parent_ )
1272  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
1273  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1274  {}
1275 
1276  sc_inout( const char* name_, this_type& parent_ )
1277  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
1278  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1279  {}
1280 
1281 
1282  // destructor
1283 
1284  virtual ~sc_inout();
1285 
1286 
1287  // interface access shortcut methods
1288 
1289  // get the default event
1290 
1291  const sc_event& default_event() const
1292  { return (*this)->default_event(); }
1293 
1294 
1295  // get the value changed event
1296 
1298  { return (*this)->value_changed_event(); }
1299 
1300  // get the positive edge event
1301 
1302  const sc_event& posedge_event() const
1303  { return (*this)->posedge_event(); }
1304 
1305  // get the negative edge event
1306 
1307  const sc_event& negedge_event() const
1308  { return (*this)->negedge_event(); }
1309 
1310 
1311  // read the current value
1312 
1313  const data_type& read() const
1314  { return (*this)->read(); }
1315 
1316  operator const data_type& () const
1317  { return (*this)->read(); }
1318 
1319 
1320  // use for positive edge sensitivity
1321 
1323  {
1324  if ( !m_pos_finder_p )
1325  {
1326  m_pos_finder_p = new sc_event_finder_t<in_if_type>(
1327  *this, &in_if_type::posedge_event );
1328  }
1329  return *m_pos_finder_p;
1330  }
1331 
1332  // use for negative edge sensitivity
1333 
1335  {
1336  if ( !m_neg_finder_p )
1337  {
1338  m_neg_finder_p = new sc_event_finder_t<in_if_type>(
1339  *this, &in_if_type::negedge_event );
1340  }
1341  return *m_neg_finder_p;
1342  }
1343 
1344 
1345  // was there a value changed event?
1346 
1347  bool event() const
1348  { return (*this)->event(); }
1349 
1350  // was there a positive edge event?
1351 
1352  bool posedge() const
1353  { return (*this)->posedge(); }
1354 
1355  // was there a negative edge event?
1356 
1357  bool negedge() const
1358  { return (*this)->negedge(); }
1359 
1360  // write the new value
1361 
1362  void write( const data_type& value_ )
1363  { (*this)->write( value_ ); }
1364 
1365  this_type& operator = ( const data_type& value_ )
1366  { (*this)->write( value_ ); return *this; }
1367 
1368  this_type& operator = ( const in_if_type& interface_ )
1369  { (*this)->write( interface_.read() ); return *this; }
1370 
1372  { (*this)->write( port_->read() ); return *this; }
1373 
1375  { (*this)->write( port_->read() ); return *this; }
1376 
1378  { (*this)->write( port_->read() ); return *this; }
1379 
1380 
1381  // set initial value (can also be called when port is not bound yet)
1382 
1383  void initialize( const data_type& value_ );
1384 
1385  void initialize( const in_if_type& interface_ )
1386  { initialize( interface_.read() ); }
1387 
1388 
1389  // called when elaboration is done
1390  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
1391  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
1392 
1393  virtual void end_of_elaboration();
1394 
1395 
1396  // (other) event finder method(s)
1397 
1399  {
1400  if ( !m_change_finder_p )
1401  {
1402  m_change_finder_p = new sc_event_finder_t<in_if_type>(
1404  }
1405  return *m_change_finder_p;
1406  }
1407 
1408  virtual const char* kind() const
1409  { return "sc_inout"; }
1410 
1411 protected:
1412 
1414 
1415 public:
1416 
1417  // called by sc_trace
1418  void add_trace_internal( sc_trace_file*, const std::string& ) const;
1419 
1420  void add_trace( sc_trace_file*, const std::string& ) const;
1421 
1422 protected:
1423 
1424  void remove_traces() const;
1425 
1427 
1428 private:
1429  mutable sc_event_finder* m_change_finder_p;
1430  mutable sc_event_finder* m_neg_finder_p;
1431  mutable sc_event_finder* m_pos_finder_p;
1432 
1433 private:
1434 
1435  // disabled
1436  sc_inout( const this_type& );
1437 
1438 #ifdef __GNUC__
1439  // Needed to circumvent a problem in the g++-2.95.2 compiler:
1440  // This unused variable forces the compiler to instantiate
1441  // an object of T template so an implicit conversion from
1442  // read() to a C++ intrinsic data type will work.
1443  static data_type dummy;
1444 #endif
1445 };
1446 
1447 
1448 // ----------------------------------------------------------------------------
1449 // CLASS : sc_inout<sc_dt::sc_logic>
1450 //
1451 // Specialization of sc_inout<T> for type sc_dt::sc_logic.
1452 // ----------------------------------------------------------------------------
1453 
1454 template <>
1455 class sc_inout<sc_dt::sc_logic>
1456 : public sc_port<sc_signal_inout_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
1457 {
1458 public:
1459 
1460  // typedefs
1461 
1463 
1467 
1472 
1473 public:
1474 
1475  // constructors
1476 
1478  : base_type(), m_init_val( 0 ), m_traces( 0 ),
1479  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1480  {}
1481 
1482  explicit sc_inout( const char* name_ )
1483  : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
1484  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1485  {}
1486 
1487  explicit sc_inout( inout_if_type& interface_ )
1488  : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
1489  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1490  {}
1491 
1492  sc_inout( const char* name_, inout_if_type& interface_ )
1493  : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
1494  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1495  {}
1496 
1497  explicit sc_inout( inout_port_type& parent_ )
1498  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
1499  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1500  {}
1501 
1502  sc_inout( const char* name_, inout_port_type& parent_ )
1503  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
1504  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1505  {}
1506 
1507  sc_inout( this_type& parent_ )
1508  : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
1509  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1510  {}
1511 
1512  sc_inout( const char* name_, this_type& parent_ )
1513  : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
1514  m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
1515  {}
1516 
1517 
1518  // destructor
1519 
1520  virtual ~sc_inout();
1521 
1522 
1523  // interface access shortcut methods
1524 
1525  // get the default event
1526 
1527  const sc_event& default_event() const
1528  { return (*this)->default_event(); }
1529 
1530 
1531  // get the value changed event
1532 
1534  { return (*this)->value_changed_event(); }
1535 
1536  // get the positive edge event
1537 
1538  const sc_event& posedge_event() const
1539  { return (*this)->posedge_event(); }
1540 
1541  // get the negative edge event
1542 
1543  const sc_event& negedge_event() const
1544  { return (*this)->negedge_event(); }
1545 
1546 
1547  // read the current value
1548 
1549  const data_type& read() const
1550  { return (*this)->read(); }
1551 
1552  operator const data_type& () const
1553  { return (*this)->read(); }
1554 
1555 
1556  // use for positive edge sensitivity
1557 
1559  {
1560  if ( !m_pos_finder_p )
1561  {
1562  m_pos_finder_p = new sc_event_finder_t<in_if_type>(
1563  *this, &in_if_type::posedge_event );
1564  }
1565  return *m_pos_finder_p;
1566  }
1567 
1568  // use for negative edge sensitivity
1569 
1571  {
1572  if ( !m_neg_finder_p )
1573  {
1574  m_neg_finder_p = new sc_event_finder_t<in_if_type>(
1575  *this, &in_if_type::negedge_event );
1576  }
1577  return *m_neg_finder_p;
1578  }
1579 
1580 
1581  // was there a value changed event?
1582 
1583  bool event() const
1584  { return (*this)->event(); }
1585 
1586  // was there a positive edge event?
1587 
1588  bool posedge() const
1589  { return (*this)->posedge(); }
1590 
1591  // was there a negative edge event?
1592 
1593  bool negedge() const
1594  { return (*this)->negedge(); }
1595 
1596  // write the new value
1597 
1598  void write( const data_type& value_ )
1599  { (*this)->write( value_ ); }
1600 
1601  this_type& operator = ( const data_type& value_ )
1602  { (*this)->write( value_ ); return *this; }
1603 
1604  this_type& operator = ( const in_if_type& interface_ )
1605  { (*this)->write( interface_.read() ); return *this; }
1606 
1608  { (*this)->write( port_->read() ); return *this; }
1609 
1611  { (*this)->write( port_->read() ); return *this; }
1612 
1614  { (*this)->write( port_->read() ); return *this; }
1615 
1616 
1617  // set initial value (can also be called when port is not bound yet)
1618 
1619  void initialize( const data_type& value_ );
1620 
1621  void initialize( const in_if_type& interface_ )
1622  { initialize( interface_.read() ); }
1623 
1624 
1625  // called when elaboration is done
1626  /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
1627  /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
1628 
1629  virtual void end_of_elaboration();
1630 
1631 
1632  // (other) event finder method(s)
1633 
1635  {
1636  if ( !m_change_finder_p )
1637  {
1638  m_change_finder_p = new sc_event_finder_t<in_if_type>(
1640  }
1641  return *m_change_finder_p;
1642  }
1643 
1644  virtual const char* kind() const
1645  { return "sc_inout"; }
1646 
1647 protected:
1648 
1650 
1651 public:
1652 
1653  // called by sc_trace
1654  void add_trace_internal( sc_trace_file*, const std::string& ) const;
1655 
1656  void add_trace( sc_trace_file*, const std::string& ) const;
1657 
1658 protected:
1659 
1660  void remove_traces() const;
1661 
1663 
1664 private:
1665  mutable sc_event_finder* m_change_finder_p;
1666  mutable sc_event_finder* m_neg_finder_p;
1667  mutable sc_event_finder* m_pos_finder_p;
1668 
1669 private:
1670 
1671  // disabled
1672  sc_inout( const this_type& );
1673 
1674 #ifdef __GNUC__
1675  // Needed to circumvent a problem in the g++-2.95.2 compiler:
1676  // This unused variable forces the compiler to instantiate
1677  // an object of T template so an implicit conversion from
1678  // read() to a C++ intrinsic data type will work.
1679  static data_type dummy;
1680 #endif
1681 };
1682 
1683 
1684 // ----------------------------------------------------------------------------
1685 // CLASS : sc_out<T>
1686 //
1687 // The sc_signal<T> output port class.
1688 // ----------------------------------------------------------------------------
1689 
1690 // sc_out can also read from its port, hence no difference with sc_inout.
1691 // For debugging reasons, a class is provided instead of a define.
1692 
1693 template <class T>
1694 class sc_out
1695 : public sc_inout<T>
1696 {
1697 public:
1698 
1699  // typedefs
1700 
1701  typedef T data_type;
1702 
1705 
1710 
1711 public:
1712 
1713  // constructors
1714 
1716  : base_type()
1717  {}
1718 
1719  explicit sc_out( const char* name_ )
1720  : base_type( name_ )
1721  {}
1722 
1723  explicit sc_out( inout_if_type& interface_ )
1724  : base_type( interface_ )
1725  {}
1726 
1727  sc_out( const char* name_, inout_if_type& interface_ )
1728  : base_type( name_, interface_ )
1729  {}
1730 
1731  explicit sc_out( inout_port_type& parent_ )
1732  : base_type( parent_ )
1733  {}
1734 
1735  sc_out( const char* name_, inout_port_type& parent_ )
1736  : base_type( name_, parent_ )
1737  {}
1738 
1739  sc_out( this_type& parent_ )
1740  : base_type( parent_ )
1741  {}
1742 
1743  sc_out( const char* name_, this_type& parent_ )
1744  : base_type( name_, parent_ )
1745  {}
1746 
1747 
1748  // destructor (does nothing)
1749 
1750  virtual ~sc_out()
1751  {}
1752 
1753 
1754  // write the new value
1755 
1756  this_type& operator = ( const data_type& value_ )
1757  { (*this)->write( value_ ); return *this; }
1758 
1759  this_type& operator = ( const in_if_type& interface_ )
1760  { (*this)->write( interface_.read() ); return *this; }
1761 
1763  { (*this)->write( port_->read() ); return *this; }
1764 
1766  { (*this)->write( port_->read() ); return *this; }
1767 
1769  { (*this)->write( port_->read() ); return *this; }
1770 
1771  virtual const char* kind() const
1772  { return "sc_out"; }
1773 
1774 private:
1775 
1776  // disabled
1777  sc_out( const this_type& );
1778 };
1779 
1780 
1781 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1782 
1783 
1784 // ----------------------------------------------------------------------------
1785 // FUNCTION : sc_trace
1786 // ----------------------------------------------------------------------------
1787 
1788 template <class T>
1789 inline
1790 void
1791 sc_trace(sc_trace_file* tf, const sc_in<T>& port, const std::string& name)
1792 {
1793  const sc_signal_in_if<T>* iface = 0;
1794  if (sc_get_curr_simcontext()->elaboration_done() )
1795  {
1796  iface = DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
1797  }
1798 
1799  if ( iface )
1800  sc_trace( tf, iface->read(), name );
1801  else
1802  port.add_trace_internal( tf, name );
1803 }
1804 
1805 template <class T>
1806 inline
1807 void
1809  const std::string& name )
1810 {
1811  const sc_signal_in_if<T>* iface = 0;
1812  if (sc_get_curr_simcontext()->elaboration_done() )
1813  {
1814  iface =DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
1815  }
1816 
1817  if ( iface )
1818  sc_trace( tf, iface->read(), name );
1819  else
1820  port.add_trace_internal( tf, name );
1821 }
1822 
1823 } // namespace sc_core
1824 
1825 #undef SC_VIRTUAL_
1826 
1827 /*****************************************************************************
1828 
1829  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
1830  changes you are making here.
1831 
1832  Name, Affiliation, Date: Jason Elbaum, Motorola, Inc., 2001-11-12
1833  Description of Modification: Added a static, private, otherwise
1834  unused data member to the sc_in
1835  and sc_inout classes to address
1836  a bug in the GNU compiler *only*.
1837  This works around a bug in g++ 2.95.2
1838  regarding implicit casting from a
1839  templated class to a C++ intrinsic type.
1840 
1841  *****************************************************************************/
1842 //$Log: sc_signal_ports.h,v $
1843 //Revision 1.10 2011/08/29 18:04:32 acg
1844 // Philipp A. Hartmann: miscellaneous clean ups.
1845 //
1846 //Revision 1.9 2011/08/26 20:45:43 acg
1847 // Andy Goodrich: moved the modification log to the end of the file to
1848 // eliminate source line number skew when check-ins are done.
1849 //
1850 //Revision 1.8 2011/08/07 19:08:01 acg
1851 // Andy Goodrich: moved logs to end of file so line number synching works
1852 // better between versions.
1853 //
1854 //Revision 1.7 2011/08/07 18:53:09 acg
1855 // Philipp A. Hartmann: add virtual instances of the bind function for
1856 // base classes to eliminate warning messages for clang platforms.
1857 //
1858 //Revision 1.6 2011/04/02 00:03:23 acg
1859 // Andy Goodrich: catch the other bind()'s that I missed in Philipp's update.
1860 //
1861 //Revision 1.5 2011/04/01 22:33:31 acg
1862 // Philipp A. Harmann: Use const interface signature to implement non-const
1863 // interface signature for virtual bind(...).
1864 //
1865 //Revision 1.4 2011/03/30 16:46:10 acg
1866 // Andy Goodrich: added a signature and removed a virtual specification
1867 // to eliminate warnings with certain compilers.
1868 //
1869 //Revision 1.3 2011/02/18 20:23:45 acg
1870 // Andy Goodrich: Copyright update.
1871 //
1872 //Revision 1.2 2011/01/20 16:52:15 acg
1873 // Andy Goodrich: changes for IEEE 1666 2011.
1874 //
1875 //Revision 1.1.1.1 2006/12/15 20:20:04 acg
1876 //SystemC 2.3
1877 //
1878 //Revision 1.11 2006/04/18 23:36:50 acg
1879 // Andy Goodrich: made add_trace_internal public until I can figure out
1880 // how to do a friend specification for sc_trace in an environment where
1881 // there are partial template and full template specifications for its
1882 // arguments.
1883 //
1884 //Revision 1.10 2006/04/18 18:01:26 acg
1885 // Andy Goodrich: added an add_trace_internal() method to the various port
1886 // classes so that sc_trace has something to call that won't emit an
1887 // IEEE 1666 deprecation message.
1888 //
1889 //Revision 1.9 2006/03/13 20:19:44 acg
1890 // Andy Goodrich: changed sc_event instances into pointers to sc_event instances
1891 // that are allocated as needed. This saves considerable storage for large
1892 // numbers of signals, etc.
1893 //
1894 //Revision 1.8 2006/02/02 23:42:37 acg
1895 // Andy Goodrich: implemented a much better fix to the sc_event_finder
1896 // proliferation problem. This new version allocates only a single event
1897 // finder for each port for each type of event, e.g., pos(), neg(), and
1898 // value_change(). The event finder persists as long as the port does,
1899 // which is what the LRM dictates. Because only a single instance is
1900 // allocated for each event type per port there is not a potential
1901 // explosion of storage as was true in the 2.0.1/2.1 versions.
1902 //
1903 //Revision 1.7 2006/02/02 21:38:12 acg
1904 // Andy Goodrich: fix to the comment log.
1905 //
1906 //Revision 1.4 2006/01/24 20:46:32 acg
1907 //Andy Goodrich: changes to eliminate use of deprecated features. For instance,
1908 //using notify(SC_ZERO_TIME) in place of notify_delayed().
1909 //
1910 //Revision 1.3 2006/01/13 18:47:42 acg
1911 //Added $Log command so that CVS comments are reproduced in the source.
1912 //
1913 //Revision 1.2 2006/01/03 23:18:26 acg
1914 //Changed copyright to include 2006.
1915 //
1916 //Revision 1.1.1.1 2005/12/19 23:16:43 acg
1917 //First check in of SystemC 2.1 into its own archive.
1918 //
1919 //Revision 1.18 2005/09/15 23:01:52 acg
1920 //Added std:: prefix to appropriate methods and types to get around
1921 //issues with the Edison Front End.
1922 //
1923 //Revision 1.17 2005/06/10 22:43:55 acg
1924 //Added CVS change log annotation.
1925 //
1926 
1927 #endif
1928 
1929 // Taf!
sc_inout(const char *name_, inout_port_type &parent_)
sc_in(in_port_type &parent_)
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
SC_VIRTUAL_ void bind(in_port_type &parent_)
sc_in(const char *name_)
virtual const char * kind() const
sc_event_finder & pos() const
sc_in(const char *name_)
SC_VIRTUAL_ void bind(const in_if_type &interface_)
virtual void end_of_elaboration()
sc_event_finder & pos() const
sc_out(inout_if_type &interface_)
virtual const char * kind() const
sc_inout(this_type &parent_)
this_type & operator=(const data_type &value_)
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
sc_out(inout_port_type &parent_)
sc_inout(inout_port_type &parent_)
sc_inout(inout_if_type &interface_)
virtual void end_of_elaboration()
sc_trace_params_vec * m_traces
const sc_event & value_changed_event() const
void initialize(const in_if_type &interface_)
void operator()(const in_if_type &interface_)
std::vector< sc_trace_params * > sc_trace_params_vec
SC_VIRTUAL_ void bind(in_if_type &interface_)
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
this_type port_type
Definition: sc_port.h:261
const data_type & read() const
const sc_event & posedge_event() const
sc_event_finder & value_changed() const
virtual const char * kind() const
sc_in(in_port_type &parent_)
virtual sc_interface * get_interface()
Definition: sc_port.h:305
const sc_event & negedge_event() const
sc_event_finder & pos() const
sc_in(const char *name_, this_type &parent_)
sc_signal_in_if< data_type > if_type
SC_VIRTUAL_ void bind(inout_port_type &parent_)
SC_VIRTUAL_ void bind(const in_if_type &interface_)
sc_port< in_if_type, 1, SC_ONE_OR_MORE_BOUND > in_port_type
SC_VIRTUAL_ void bind(inout_port_type &parent_)
sc_port< in_if_type, 1, SC_ONE_OR_MORE_BOUND > in_port_type
const data_type & read() const
sc_trace_params_vec * m_traces
sc_signal_inout_if< data_type > inout_if_type
sc_inout(const char *name_, inout_port_type &parent_)
sc_event_finder & neg() const
SC_VIRTUAL_ void bind(in_if_type &interface_)
sc_inout(const char *name_, inout_if_type &interface_)
sc_signal_inout_if< data_type > if_type
void write(const data_type &value_)
sc_signal_in_if< data_type > if_type
sc_inout(inout_if_type &interface_)
const data_type & read() const
sc_event_finder & value_changed() const
const sc_event & negedge_event() const
sc_event_finder & pos() const
SC_VIRTUAL_ void bind(base_port_type &parent_)
SC_VIRTUAL_ void bind(in_port_type &parent_)
sc_in(const char *name_, in_port_type &parent_)
const sc_event & posedge_event() const
const sc_event & posedge_event() const
sc_in< data_type > this_type
sc_inout(inout_port_type &parent_)
const sc_event & negedge_event() const
sc_trace_params_vec * m_traces
void initialize(const data_type &value_)
sc_signal_inout_if< data_type > if_type
const sc_event & value_changed_event() const
this_type & operator=(const data_type &value_)
SC_VIRTUAL_ void bind(inout_port_type &parent_)
sc_inout< data_type > base_type
sc_in(this_type &parent_)
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
bool event() const
sc_event_finder & value_changed() const
void add_trace_internal(sc_trace_file *, const std::string &) const
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
sc_out(const char *name_, inout_if_type &interface_)
sc_in(const char *name_, in_port_type &parent_)
sc_event_finder & neg() const
sc_in(inout_port_type &parent_)
sc_in(this_type &parent_)
const sc_event & default_event() const
void add_trace(sc_trace_file *, const std::string &) const
sc_simcontext * sc_get_curr_simcontext()
data_type * m_init_val
const sc_event & default_event() const
const sc_signal_in_if< T > * get_interface(int iface_i) const
virtual const sc_event & value_changed_event() const =0
sc_in(const char *name_, const in_if_type &interface_)
sc_event_finder & neg() const
virtual const char * kind() const
virtual int vbind(sc_interface &)
sc_port< inout_if_type, 1, SC_ONE_OR_MORE_BOUND > inout_port_type
sc_event_finder & value_changed() const
sc_in(const char *name_, this_type &parent_)
sc_out(const char *name_, inout_port_type &parent_)
sc_in(const in_if_type &interface_)
sc_out< data_type > this_type
const sc_event & negedge_event() const
const sc_event & value_changed_event() const
sc_out(const char *name_, this_type &parent_)
sc_inout(const char *name_, this_type &parent_)
const sc_event & value_changed_event() const
const data_type & read() const
sc_inout(inout_port_type &parent_)
void remove_traces() const
sc_in(const char *name_, inout_port_type &parent_)
sc_in(const in_if_type &interface_)
const sc_event & default_event() const
sc_port< inout_if_type, 1, SC_ONE_OR_MORE_BOUND > inout_port_type
sc_inout(const char *name_, this_type &parent_)
sc_in(const char *name_, inout_port_type &parent_)
bool event() const
const sc_event & posedge_event() const
sc_signal_in_if< data_type > in_if_type
const sc_event & default_event() const
base_type::port_type base_port_type
sc_inout(const char *name_, inout_port_type &parent_)
sc_signal_in_if< data_type > in_if_type
virtual const T & read() const =0
virtual const char * kind() const
#define SC_VIRTUAL_
virtual const char * kind() const
sc_inout(const char *name_)
sc_port< in_if_type, 1, SC_ONE_OR_MORE_BOUND > in_port_type
sc_signal_inout_if< data_type > if_type
SC_VIRTUAL_ void bind(base_port_type &parent_)
#define CCAST
Definition: sc_iostream.h:56
sc_in(const char *name_, this_type &parent_)
SC_VIRTUAL_ void bind(const in_if_type &interface_)
const data_type & read() const
void initialize(const in_if_type &interface_)
base_type::in_port_type in_port_type
sc_inout(this_type &parent_)
void add_trace_internal(sc_trace_file *, const std::string &) const
sc_trace_params(sc_trace_file *tf_, const std::string &name_)
sc_out(this_type &parent_)
sc_inout(const char *name_, inout_if_type &interface_)
base_type::in_if_type in_if_type
sc_in(const in_if_type &interface_)
sc_inout(const char *name_)
sc_inout< data_type > this_type
base_type::inout_if_type inout_if_type
sc_signal_inout_if< data_type > inout_if_type
sc_port< inout_if_type, 1, SC_ONE_OR_MORE_BOUND > inout_port_type
virtual void write(const T &)=0
sc_in(const char *name_, const in_if_type &interface_)
virtual const char * kind() const
sc_port< if_type, 1, SC_ONE_OR_MORE_BOUND > base_type
sc_out(const char *name_)
sc_signal_in_if< data_type > in_if_type
base_type::inout_port_type inout_port_type
void remove_traces() const
sc_inout(inout_if_type &interface_)
SC_VIRTUAL_ void bind(base_port_type &parent_)
base_type in_port_type
base_type inout_port_type
const sc_event & value_changed_event() const
const data_type & read() const
sc_in(const char *name_, const in_if_type &interface_)
SC_VIRTUAL_ void bind(in_port_type &parent_)
sc_in(const char *name_, inout_port_type &parent_)
void add_trace(sc_trace_file *, const std::string &) const
sc_in< data_type > this_type
sc_signal_inout_if< data_type > inout_if_type
void write(const data_type &value_)
const sc_event & default_event() const
void sc_trace(sc_trace_file *tf, const sc_in< T > &port, const std::string &name)
sc_event_finder & value_changed() const
sc_inout(const char *name_, this_type &parent_)
void initialize(const in_if_type &interface_)
void bind(sc_interface &interface_)
const sc_event & default_event() const
sc_inout< data_type > this_type
void write(const data_type &value_)
void sc_deprecated_add_trace()
base_type::port_type base_port_type
sc_in(inout_port_type &parent_)
sc_trace_params_vec * m_traces
sc_event_finder & neg() const
virtual int vbind(sc_interface &)
Definition: sc_port.h:507
base_type::port_type base_port_type
sc_inout(const char *name_, inout_if_type &interface_)
sc_in(const char *name_, in_port_type &parent_)
sc_signal_in_if< data_type > if_type
const sc_event & value_changed_event() const
SC_VIRTUAL_ void bind(in_if_type &interface_)
sc_in(inout_port_type &parent_)
sc_event_finder & value_changed() const