scx_signal_int.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2004 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_signal_uint.h -- The sc_signal<sc_dt::sc_int<W> > definitions.
00021 
00022   Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
00033 
00034  *****************************************************************************/
00035 
00036 /* 
00037 $Log: sc_signal_int.h,v $
00038 Revision 1.21  2005/03/21 22:31:32  acg
00039 Changes to sc_core namespace.
00040 
00041 Revision 1.20  2005/01/10 17:51:58  acg
00042 Improvements.
00043 
00044 Revision 1.19  2004/11/09 00:11:26  acg
00045 Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
00046 now is derived from sc_generic_base<sc_concatref>.
00047 
00048 Revision 1.18  2004/09/27 21:01:59  acg
00049 Andy Goodrich - Forte Design Systems, Inc.
00050    - This is specialized signal support that allows better use of signals
00051      and ports whose target value is a SystemC native type.
00052 
00053 */
00054 
00055 
00056 #if !defined(SC_SIGNAL_INT_H)
00057 #define SC_SIGNAL_INT_H
00058 
00059 #if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
00060 #    define SC_TEMPLATE template<int W>
00061 #else
00062 #    define SC_TEMPLATE template<> template<int W>
00063 #endif
00064 
00065 
00066 // FORWARD REFERENCES AND USINGS:
00067 
00068 
00069 namespace sc_core {
00070 
00071 class sc_int_sigref;
00072 
00073 //==============================================================================
00074 // CLASS sc_int_part_if
00075 //
00076 // This class provides generic access to part selections for signals whose
00077 // data type is sc_dt::sc_int<W>. This class serves as the base class for the
00078 // sc_dt::sc_int<W> specialization of the sc_signal_in_if<T> class. The methods
00079 // in this class may be over-ridden individually, those that are not overridden
00080 // will produce an error message when called. The methods are used by the 
00081 // sc_int_sigref class.
00082 //
00083 // Notes:
00084 //   (1) Descriptions of the methods and operators in this class appear with
00085 //       their implementations in sc_signal<sc_dt::sc_int<W> >.
00086 //==============================================================================
00087 class sc_int_part_if : virtual public sc_interface {
00088   protected:
00089         // constructor:
00090         sc_int_part_if() {}
00091 
00092   public:
00093     // perform a part read.
00094         virtual sc_dt::sc_int_base* part_read_target();
00095         virtual sc_dt::uint64 read_part( int left, int right ) const;
00096 
00097     // perform a part write.
00098         virtual sc_int_sigref& select_part( int left, int right );
00099         virtual void write_part( sc_dt::uint64 v, int left, int right );
00100 
00101   private:
00102         sc_int_part_if( const sc_int_part_if& );
00103         sc_int_part_if& operator = ( const sc_int_part_if& );
00104 };
00105 
00106 
00107 //==============================================================================
00108 // CLASS sc_signal_in_if<sc_dt::sc_int<W> >
00109 //
00110 // This is the class specializations for the sc_signal_in_if<T> class to
00111 // provide additional features for sc_signal instances whose template is
00112 // sc_dt::sc_int<W>, including part access. 
00113 //
00114 // Notes:
00115 //   (1) Descriptions of the methods and operators in this class appear with
00116 //       their implementations in sc_signal<sc_dt::sc_int<W> >.
00117 //==============================================================================
00118 template< int W >
00119 class sc_signal_in_if<sc_dt::sc_int<W> > : public sc_int_part_if {
00120         friend class sc_int_sigref;
00121   public:
00122     typedef sc_signal_in_if<sc_dt::sc_int<W> > this_type;
00123 
00124     // get the value changed event
00125     virtual const sc_event& value_changed_event() const = 0;
00126 
00127 
00128     // read the current value
00129     virtual const sc_dt::sc_int<W>& read() const = 0;
00130 
00131     // get a reference to the current value (for tracing)
00132     virtual const sc_dt::sc_int<W>& get_data_ref() const = 0;
00133 
00134 
00135     // was there a value changed event?
00136     virtual bool event() const = 0;
00137 
00138   protected: 
00139     // constructor
00140     sc_signal_in_if()
00141     {}
00142 
00143   private: // disabled 
00144     sc_signal_in_if( const this_type& );
00145     this_type& operator = ( const this_type& );
00146 };
00147 
00148 //=============================================================================
00149 //  CLASS : sc_int_sigref
00150 //
00151 //  Proxy class for sc_signal_int bit and part selection.
00152 //=============================================================================
00153 class sc_int_sigref : public sc_dt::sc_int_subref_r
00154 {
00155   public:
00156     sc_int_sigref() : sc_dt::sc_int_subref_r() {}
00157     virtual ~sc_int_sigref() {}
00158     virtual void concat_set(sc_dt::int64 src, int low_i);
00159     virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
00160     virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
00161     virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
00162     virtual void concat_set(sc_dt::uint64 src, int low_i);
00163 
00164   public:
00165     inline void initialize( sc_int_part_if* if_p, int left_, int right_ );
00166 
00167   public:
00168     inline void operator = ( sc_dt::uint64 v );
00169     inline void operator = ( const char* v );
00170     inline void operator = ( unsigned long v );
00171     inline void operator = ( long v );
00172     inline void operator = ( unsigned int v );
00173     inline void operator = ( int v );
00174     inline void operator = ( sc_dt::int64 v );
00175     inline void operator = ( double v );
00176     inline void operator = ( const sc_int_sigref& v );
00177     template<typename T>
00178     inline void operator = ( const sc_dt::sc_generic_base<T>& v );
00179     inline void operator = ( const sc_dt::sc_signed& v );
00180     inline void operator = ( const sc_dt::sc_unsigned& v );
00181     inline void operator = ( const sc_dt::sc_bv_base& v );
00182     inline void operator = ( const sc_dt::sc_lv_base& v );
00183 
00184   public:
00185     static sc_vpool<sc_int_sigref> m_pool; // Pool of objects to use.
00186 
00187   protected:
00188     sc_int_part_if*                m_if_p; // Target for selection.
00189 
00190   private:
00191 
00192     // disabled
00193     sc_int_sigref( const sc_int_sigref& a );
00194 };
00195 
00196 
00197 //==============================================================================
00198 // CLASS sc_signal<sc_dt::sc_int<W> > 
00199 //
00200 // This class implements a signal whose value acts like an sc_dt::sc_int<W> data
00201 // value. This class is a specialization of the generic sc_signal class to 
00202 // implement tailored support for the sc_dt::sc_int<W> class.
00203 //
00204 // Notes:
00205 //   (1) Descriptions of the methods and operators in this class appear with
00206 //       their implementations.
00207 //==============================================================================
00208 SC_TEMPLATE
00209 class sc_signal<sc_dt::sc_int<W> > : 
00210     public sc_signal_inout_if<sc_dt::sc_int<W> >,
00211         public sc_prim_channel,
00212     public sc_dt::sc_int<W>
00213 {
00214   public: // typedefs
00215     typedef sc_signal<sc_dt::sc_int<W> > this_type;
00216 
00217   public: // constructors and destructor:
00218     inline sc_signal();
00219     explicit inline sc_signal(const char* name_);
00220     virtual inline ~sc_signal();
00221 
00222   public: // base methods:
00223     inline bool base_event() const;
00224     inline const sc_dt::sc_int<W>& base_read() const;
00225     inline const sc_event& base_value_changed_event() const;
00226     inline void base_write( sc_dt::int64 value );
00227 
00228   public: // sc_prim_channel virtual methods:
00229     virtual inline const char* kind() const;
00230     virtual inline void update();
00231 
00232   public: // sc_interface virtual methods:
00233     virtual inline const sc_event& default_event() const;
00234     virtual inline void register_port( 
00235                 sc_port_base& port_, const char* if_typename_ );
00236 
00237   public: // sc_int_part_if virtual methods:
00238     virtual inline sc_dt::sc_int_base* part_read_target();
00239     virtual inline sc_dt::uint64 read_part(int left, int right) const;
00240         virtual inline sc_int_sigref& select_part(int left, int right);
00241         virtual inline void write_part(sc_dt::uint64 v, int left, int right);
00242 
00243   public: // interface virtual methods:
00244     virtual inline bool event() const;
00245     virtual inline const sc_dt::sc_int<W>& get_data_ref() const;
00246     virtual inline sc_signal<sc_dt::sc_int<W> >& get_signal() ;
00247     virtual inline const sc_dt::sc_int<W>& read() const;
00248     virtual inline const sc_event& value_changed_event() const;
00249     virtual inline void write( const sc_in<sc_dt::sc_int<W> >& value );
00250     virtual inline void write( const sc_inout<sc_dt::sc_int<W> >& value );
00251     virtual inline void write( const sc_dt::sc_int<W>& value );
00252 
00253   public: // part selections:
00254         inline sc_int_sigref& operator () ( int left, int right );
00255         inline sc_int_sigref& operator [] ( int bit );
00256 
00257   public: // operators:
00258     inline void operator = ( const this_type& new_val );
00259     inline void operator = ( const char* new_val );
00260     inline void operator = ( sc_dt::uint64 new_val );
00261     inline void operator = ( sc_dt::int64 new_val );
00262     inline void operator = ( int new_val );
00263     inline void operator = ( long new_val ) ;
00264     inline void operator = ( short new_val ) ;
00265     inline void operator = ( unsigned int new_val ) ;
00266     inline void operator = ( unsigned long new_val );
00267     inline void operator = ( unsigned short new_val );
00268     template<typename T>
00269     inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
00270     inline void operator = ( const sc_dt::sc_signed& new_val );
00271     inline void operator = ( const sc_dt::sc_unsigned& new_val );
00272     inline void operator = ( const sc_dt::sc_bv_base& new_val );
00273     inline void operator = ( const sc_dt::sc_lv_base& new_val );
00274 
00275     // concatenation methods (we inherit length and gets from sc_dt::sc_int<W>):
00276 
00277     virtual inline void concat_set(sc_dt::int64 src, int low_i);
00278     virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
00279     virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
00280     virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
00281     virtual inline void concat_set(sc_dt::uint64 src, int low_i);
00282 
00283   protected: // debugging methods:
00284     // #### void check_port();
00285         void check_writer();
00286 
00287   private: // Disabled operations that sc_dt::sc_int<W> supports:
00288     sc_signal<sc_dt::sc_int<W> >& operator ++ ();          // prefix
00289     const sc_signal<sc_dt::sc_int<W> >& operator ++ (int); // postfix
00290     sc_signal<sc_dt::sc_int<W> >& operator -- ();          // prefix
00291     const sc_signal<sc_dt::sc_int<W> >& operator -- (int); // postfix
00292     sc_signal<sc_dt::sc_int<W> >& operator += (sc_dt::int_type);
00293     sc_signal<sc_dt::sc_int<W> >& operator -= (sc_dt::int_type);
00294     sc_signal<sc_dt::sc_int<W> >& operator *= (sc_dt::int_type);
00295     sc_signal<sc_dt::sc_int<W> >& operator /= (sc_dt::int_type);
00296     sc_signal<sc_dt::sc_int<W> >& operator %= (sc_dt::int_type);
00297     sc_signal<sc_dt::sc_int<W> >& operator &= (sc_dt::int_type);
00298     sc_signal<sc_dt::sc_int<W> >& operator |= (sc_dt::int_type);
00299     sc_signal<sc_dt::sc_int<W> >& operator ^= (sc_dt::int_type);
00300 
00301   protected:
00302     mutable sc_event* m_changed_event_p; // Value changed event this object.
00303     sc_dt::uint64            m_event_delta;     // Delta cycle of last event.
00304     sc_dt::int64             m_new_val;         // New value for this object instance.
00305     sc_port_base*     m_output_p;        // Single write port verify field.
00306     sc_process_b*     m_writer_p;        // Single writer verify field.
00307 };
00308 
00309 
00310 SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
00311 inline bool sc_signal<sc_dt::sc_int<W> >::base_event() const
00312 {
00313     return simcontext()->delta_count() == m_event_delta + 1;
00314 }
00315 
00316 
00317 SC_TEMPLATE // Return this object's sc_dt::sc_int<W> object instance.
00318 inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::base_read() const
00319 {
00320         return *this;
00321 }
00322 
00323 
00324 SC_TEMPLATE // Return the value changed event, allocating it if necessary.
00325 inline const sc_event& sc_signal<sc_dt::sc_int<W> >::base_value_changed_event() const
00326 {
00327     if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
00328     return *m_changed_event_p;
00329 }
00330 
00331 
00332 SC_TEMPLATE // Select a portion of a value. 
00333 inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::select_part(int left, int right)
00334 {
00335     sc_int_sigref* result_p = sc_int_sigref::m_pool.allocate();
00336     result_p->initialize(this, left, right);
00337     return *result_p;
00338 }
00339 
00340 
00341 SC_TEMPLATE // Write an sc_dt::uint64 value to this object instance.
00342 inline void sc_signal<sc_dt::sc_int<W> >::base_write( sc_dt::int64 value )
00343 {
00344 #   if defined(DEBUG_SYSTEMC)
00345         check_writer();
00346 #   endif
00347     m_new_val = value;
00348     request_update();
00349 }
00350 
00351 //------------------------------------------------------------------------------
00352 //"sc_signal<sc_dt::sc_int<W> >::check_writer"
00353 //
00354 // This method checks to see if there is more than one writer for this 
00355 // object instance by keeping track of the process performing the write.
00356 //------------------------------------------------------------------------------
00357 SC_TEMPLATE
00358 inline void sc_signal<sc_dt::sc_int<W> >::check_writer()
00359 {
00360     sc_process_b* writer_p = sc_get_curr_process_handle();
00361     if( m_writer_p == 0 ) 
00362     {   
00363         m_writer_p = writer_p;
00364     } 
00365     else if( m_writer_p != writer_p ) 
00366     {   
00367         sc_signal_invalid_writer( name(), kind(),
00368                                   m_writer_p->name(), writer_p->name() );
00369     }
00370 }
00371 
00372 
00373 //------------------------------------------------------------------------------
00374 //"sc_signal<sc_dt::sc_int<W> >::concat_set"
00375 //
00376 // These virtual methods allow value assignments to this object instance
00377 // from various sources. The position within the supplied source of the 
00378 // low order bit for this object instance's value is low_i.
00379 //     src   = source value.
00380 //     low_i = bit within src to serve as low order bit of this object 
00381 //             instance's value.
00382 //------------------------------------------------------------------------------
00383 SC_TEMPLATE
00384 inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::int64 src, int low_i)
00385 {
00386     if ( low_i < 64 )
00387     {
00388         base_write(src >> low_i);
00389     }
00390     else
00391     {
00392         base_write( src >> 63 );
00393     } 
00394 }
00395 
00396 SC_TEMPLATE
00397 inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_lv_base& src, int low_i)
00398 {
00399     sc_dt::sc_unsigned tmp(src.length());
00400     tmp = src >> low_i;
00401     base_write( tmp.to_int64() );
00402 }
00403 
00404 SC_TEMPLATE
00405 inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_signed& src, int low_i)
00406 {
00407     base_write( (src >> low_i).to_int64());
00408 }
00409 
00410 SC_TEMPLATE
00411 inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_unsigned& src, int low_i)
00412 {
00413     base_write( (src >> low_i).to_int64());
00414 }
00415 
00416 SC_TEMPLATE
00417 inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::uint64 src, int low_i)
00418 {
00419     base_write( ( low_i < 64 ) ? src >> low_i : 0 );
00420 }
00421 
00422 
00423 
00424 SC_TEMPLATE // Return the default event for this object instance.
00425 inline const sc_event& sc_signal<sc_dt::sc_int<W> >::default_event() const 
00426         { return base_value_changed_event(); }
00427 
00428 
00429 SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
00430 inline bool sc_signal<sc_dt::sc_int<W> >::event() const
00431         { return base_event(); }
00432 
00433 
00434 SC_TEMPLATE // Return a reference to the value of this object instance.
00435 inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::get_data_ref() const
00436         { return *this; }
00437 
00438 
00439 SC_TEMPLATE // Return a pointer to this object instance.
00440 inline sc_signal<sc_dt::sc_int<W> >& sc_signal<sc_dt::sc_int<W> >::get_signal() 
00441         { return *this; }
00442 
00443 
00444 SC_TEMPLATE // Return a kind value of "sc_signal".
00445 inline const char* sc_signal<sc_dt::sc_int<W> >::kind() const
00446 {
00447         return "sc_signal";
00448 }
00449 
00450 
00451 //------------------------------------------------------------------------------
00452 //"sc_signal_uint::operator ()
00453 //
00454 // This operator returns a part selection of this object instance.
00455 //     left  = left-hand bit of the selection.
00456 //     right = right-hand bit of the selection.
00457 //------------------------------------------------------------------------------
00458 SC_TEMPLATE
00459 inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator () (int left, int right)
00460 {
00461     sc_int_sigref* result_p;   // Value to return.
00462 
00463         result_p = sc_int_sigref::m_pool.allocate();
00464         result_p->initialize(this, left, right);
00465         return *result_p;
00466 }
00467 
00468 
00469 //------------------------------------------------------------------------------
00470 //"sc_signal_uint::operator []"
00471 //
00472 // This operator returns a bit selection of this object instance.
00473 //     i = bit to be selected.
00474 //------------------------------------------------------------------------------
00475 SC_TEMPLATE
00476 inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator [] ( int bit )
00477 {
00478     return operator () (bit,bit);
00479 }
00480 
00481 
00482 SC_TEMPLATE
00483 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const this_type& new_val )
00484         { base_write( (sc_dt::int64)new_val ); }
00485 
00486 SC_TEMPLATE 
00487 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const char* new_val )
00488         { m_new_val = sc_dt::sc_int<64>(new_val); request_update(); }
00489 
00490 SC_TEMPLATE
00491 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::uint64 new_val )
00492         { base_write((sc_dt::int64)new_val); }
00493 
00494 SC_TEMPLATE
00495 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::int64 new_val )
00496         { base_write(new_val); }
00497 
00498 SC_TEMPLATE
00499 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( int new_val )
00500         { base_write((sc_dt::int64)new_val); }
00501 
00502 SC_TEMPLATE
00503 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( long new_val ) 
00504         { base_write((sc_dt::int64)new_val); }
00505 
00506 SC_TEMPLATE
00507 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( short new_val ) 
00508         { base_write((sc_dt::int64)new_val); }
00509 
00510 SC_TEMPLATE
00511 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned int new_val ) 
00512         { base_write((sc_dt::int64)new_val); }
00513 
00514 SC_TEMPLATE
00515 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned long new_val )
00516         { base_write((sc_dt::int64)new_val); }
00517 
00518 SC_TEMPLATE
00519 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned short new_val )
00520         { base_write((sc_dt::int64)new_val); }
00521 
00522 
00523 SC_TEMPLATE
00524 template<typename T>
00525 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( 
00526         const sc_dt::sc_generic_base<T>& new_val )
00527         { base_write(new_val->to_int64()); }
00528 
00529 SC_TEMPLATE
00530 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_signed& new_val )
00531         { base_write(new_val.to_int64()); }
00532 
00533 SC_TEMPLATE
00534 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
00535         { base_write(new_val.to_int64()); }
00536 
00537 SC_TEMPLATE
00538 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
00539         { base_write( (sc_dt::sc_int<W>)new_val ); }
00540 
00541 SC_TEMPLATE
00542 inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
00543         { base_write( (sc_dt::sc_int<W>)new_val ); }
00544 
00545 
00546 SC_TEMPLATE
00547 inline sc_dt::sc_int_base* sc_signal<sc_dt::sc_int<W> >::part_read_target()
00548         { return this; }
00549 
00550 
00551 SC_TEMPLATE
00552 inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::read() const
00553         { return *this; }
00554 
00555 
00556 SC_TEMPLATE // Read a portion of a value.
00557 inline sc_dt::uint64 sc_signal<sc_dt::sc_int<W> >::read_part( int left, int right ) const
00558 {
00559         // This pointer required for HP aCC.
00560     return (this->m_val & ~sc_dt::mask_int[left][right]) >> right;
00561 }
00562 
00563 SC_TEMPLATE
00564 inline void sc_signal<sc_dt::sc_int<W> >::register_port( 
00565         sc_port_base& port_, const char* if_typename_ )
00566 {
00567 #       ifdef DEBUG_SYSTEMC
00568                 std::string nm( if_typename_ );
00569                 if( nm == typeid( sc_signal_inout_if<sc_dt::sc_int<W> > ).name() ) 
00570                 {
00571                         if( m_output_p != 0 ) 
00572                         {
00573                                 sc_signal_invalid_writer( name(), kind(),
00574                                          m_output_p->name(), port_.name() );
00575                         }
00576                         m_output_p = &port_;
00577                 }
00578 #       endif
00579 }
00580 
00581 
00582 SC_TEMPLATE // Autogenerated name object instance constructor.
00583 inline sc_signal<sc_dt::sc_int<W> >::sc_signal() : 
00584         sc_prim_channel(sc_gen_unique_name( "signal" )),
00585         m_changed_event_p(0),
00586         m_output_p(0),
00587         m_writer_p(0)
00588 { }
00589 
00590 
00591 SC_TEMPLATE // Explicitly named object instance constructor.
00592 inline sc_signal<sc_dt::sc_int<W> >::sc_signal(const char* name_) : 
00593         sc_prim_channel(name_),
00594         m_changed_event_p(0),
00595         m_output_p(0),
00596         m_writer_p(0)
00597 { }
00598 
00599 
00600 SC_TEMPLATE // Object instance destructor.
00601 inline sc_signal<sc_dt::sc_int<W> >::~sc_signal() 
00602 {
00603         if ( m_changed_event_p ) delete m_changed_event_p;
00604 }
00605 
00606 
00607 SC_TEMPLATE // Update the current value from new value.
00608 inline void sc_signal<sc_dt::sc_int<W> >::update()
00609 {
00610     if ( m_changed_event_p )
00611     {
00612                 // This pointer required for HP aCC.
00613         sc_dt::int64 old_val = this->m_val;
00614         sc_dt::sc_int_base::operator = (m_new_val);
00615         if ( old_val != this->m_val )
00616         {
00617             m_changed_event_p->notify_delayed();
00618             m_event_delta = simcontext()->delta_count();
00619         }
00620     }
00621     else
00622     {
00623         sc_dt::sc_int_base::operator = (m_new_val);
00624     }
00625 }
00626 
00627 
00628 SC_TEMPLATE // Return the value changed event.
00629 inline const sc_event& sc_signal<sc_dt::sc_int<W> >::value_changed_event() const
00630         { return base_value_changed_event(); }
00631 
00632 
00633 SC_TEMPLATE // Write a sc_in<sc_dt::sc_int<W> > value to this object instance.
00634 inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_in<sc_dt::sc_int<W> >& value ) 
00635         { base_write( value.operator sc_dt::int64 () ); }
00636 
00637 
00638 SC_TEMPLATE // Write a sc_inout<sc_dt::sc_int<W> > value to this object instance.
00639 inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_inout<sc_dt::sc_int<W> >& value ) 
00640         { base_write( value.operator sc_dt::int64 () ); }
00641 
00642 
00643 SC_TEMPLATE // Write a sc_dt::sc_int<W> value to this object instance.
00644 inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_dt::sc_int<W>& value ) 
00645         { base_write( value); }
00646 
00647 
00648 SC_TEMPLATE // Write a portion of a value. If this is the first write in 
00649             // a delta cycle we copy the existing value before setting the bits.
00650 inline void sc_signal<sc_dt::sc_int<W> >::write_part( sc_dt::uint64 v, int left, int right ) 
00651 {
00652     sc_dt::int64  new_v;   // New value.
00653     sc_dt::uint64 keep;    // Keep mask value.
00654 
00655     keep = sc_dt::mask_int[left][right];
00656     new_v = (m_new_val & keep) | ((v << right) & ~keep);
00657         if ( m_new_val != new_v ) request_update();
00658     m_new_val = new_v;
00659 }
00660 
00661 
00662 //==============================================================================
00663 // CLASS sc_in<sc_dt::sc_int<W> >
00664 //
00665 // This class implements an input port whose target acts like an sc_dt::sc_int<W> data
00666 // value. This class is a specialization of the generic sc_in class to 
00667 // implement tailored support for the sc_dt::sc_int<W> class.
00668 //==============================================================================
00669 SC_TEMPLATE
00670 class sc_in<sc_dt::sc_int<W> > : 
00671     public sc_port<sc_signal_in_if<sc_dt::sc_int<W> >, 1>,
00672     public sc_dt::sc_value_base
00673 {
00674   public:
00675 
00676     // typedefs
00677 
00678     typedef sc_dt::sc_int<W>                      data_type;
00679     typedef sc_signal_in_if<sc_dt::sc_int<W> >    if_type;
00680     typedef sc_port<if_type,1>                    base_type;
00681     typedef sc_in<sc_dt::sc_int<W> >              this_type;
00682 
00683     typedef if_type                               in_if_type;
00684     typedef base_type                             in_port_type;
00685     typedef sc_signal_inout_if<sc_dt::sc_int<W> > inout_if_type;
00686     typedef sc_inout<sc_dt::sc_int<W> >           inout_port_type;
00687 
00688   public:
00689 
00690     // bind methods and operators:
00691 
00692     void bind( const in_if_type& interface_ ) 
00693         { sc_port_base::bind( CCAST<in_if_type&>( interface_) );}
00694     void operator () ( const in_if_type& interface_ )
00695         { sc_port_base::bind( CCAST<in_if_type&>( interface_) );}
00696     void bind( in_port_type& parent_ )
00697         { sc_port_base::bind(parent_);}
00698     void operator () ( in_port_type& parent_ )
00699         { sc_port_base::bind(parent_);}
00700     void bind( inout_port_type& parent_ )
00701         { sc_port_base::bind(parent_);}
00702     void operator () ( inout_port_type& parent_ )
00703         { sc_port_base::bind(parent_);}
00704 
00705   protected:
00706     // called by pbind (for internal use only)
00707     virtual inline int vbind( sc_interface& interface_ )
00708         {
00709             return sc_port_b<if_type>::vbind( interface_ );
00710         }       
00711     virtual inline int vbind( sc_port_base& parent_ )
00712         {
00713             in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );  
00714             if( in_parent != 0 ) {
00715                 sc_port_base::bind( *in_parent );
00716                 return 0;
00717             }
00718             inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
00719             if( inout_parent != 0 ) {
00720                 sc_port_base::bind( *inout_parent );
00721                 return 0;
00722             }
00723             // type mismatch
00724             return 2;     
00725         }
00726 
00727 
00728     // constructors
00729 
00730   public:
00731     sc_in()
00732         : base_type(), m_traces( 0 )
00733         {}
00734 
00735     explicit sc_in( const char* name_ )
00736         : base_type( name_ ), m_traces( 0 )
00737         {}
00738 
00739     explicit sc_in( const in_if_type& interface_ )
00740         : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 )
00741         {}
00742 
00743     sc_in( const char* name_, const in_if_type& interface_ )     
00744         : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 )
00745         {}
00746 
00747     explicit sc_in( in_port_type& parent_ )
00748         : base_type( parent_ ), m_traces( 0 )
00749         {}
00750 
00751     sc_in( const char* name_, in_port_type& parent_ )
00752         : base_type( name_, parent_ ), m_traces( 0 )  
00753         {}
00754 
00755     explicit sc_in( inout_port_type& parent_ )
00756         : base_type(), m_traces( 0 )
00757         { sc_port_base::bind( parent_ ); }
00758 
00759     sc_in( const char* name_, inout_port_type& parent_ )
00760         : base_type( name_ ), m_traces( 0 )
00761         { sc_port_base::bind( parent_ ); }
00762 
00763     sc_in( this_type& parent_ )
00764         : base_type( parent_ ), m_traces( 0 )
00765         {}
00766 
00767     sc_in( const char* name_, this_type& parent_ )
00768         : base_type( name_, parent_ ), m_traces( 0 )
00769         {}
00770 
00771 
00772     // destructor
00773 
00774     virtual inline ~sc_in()
00775         {
00776             remove_traces();
00777         }
00778 
00779     // bit and part selection
00780 
00781     sc_dt::sc_int_bitref_r operator [] ( int i ) const
00782         { return (*this)->read()[i]; }
00783     sc_dt::sc_int_bitref_r bit( int i ) const
00784         { return (*this)->read()[i]; }
00785     sc_dt::sc_int_subref_r operator () ( int left, int right ) const
00786         { return (*this)->read()(left,right); }
00787     sc_dt::sc_int_subref_r range( int left, int right ) const
00788         { return (*this)->read()(left,right); }
00789 
00790 
00791     // interface access shortcut methods
00792 
00793     // get the default event
00794 
00795     const sc_event& default_event() const
00796         { return (*this)->value_changed_event(); }
00797 
00798 
00799     // get the value changed event
00800 
00801     const sc_event& value_changed_event() const
00802         { return (*this)->value_changed_event(); }
00803 
00804 
00805     // read the current value
00806 
00807     const sc_dt::sc_int<W>& read() const
00808         { return (*this)->read(); }
00809 
00810         operator sc_dt::int64 () const
00811                 { return (sc_dt::int64)(*this)->read(); }
00812 
00813     // was there a value changed event?
00814 
00815     bool event() const
00816         { return (*this)->event(); }
00817 
00818 
00819     // (other) event finder method(s)
00820 
00821     sc_event_finder& value_changed() const
00822         {
00823             return *new sc_event_finder_t<in_if_type>(
00824                 *this, &in_if_type::value_changed_event );
00825         }
00826 
00827 
00828 
00829     // reduction methods:
00830 
00831     inline bool and_reduce() const
00832         { return (*this)->read().and_reduce(); }
00833     inline bool nand_reduce() const
00834         { return (*this)->read().nand_reduce(); }
00835     inline bool nor_reduce() const
00836         { return (*this)->read().nor_reduce(); }
00837     inline bool or_reduce() const
00838         { return (*this)->read().or_reduce(); }
00839     inline bool xnor_reduce() const
00840         { return (*this)->read().xnor_reduce(); }
00841     inline bool xor_reduce() const
00842         { return (*this)->read().xor_reduce(); }
00843 
00844 
00845     // called when elaboration is done
00846     /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
00847     /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
00848 
00849     virtual inline void end_of_elaboration()
00850         {
00851             if( m_traces != 0 ) {
00852                 for( int i = 0; i < m_traces->size(); ++ i ) {
00853                     sc_trace_params* p = (*m_traces)[i];
00854                     sc_trace( p->tf, read(), p->name );
00855                 }
00856                 remove_traces();
00857             }
00858         }
00859 
00860     virtual inline const char* kind() const 
00861         { return "sc_in"; }
00862 
00863 
00864     // called by sc_trace
00865     void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
0086