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