/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/

/*****************************************************************************

  sc_signal_signed.cpp -- The sc_signal<sc_bigint<W> > implementations.

  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/

/* 
$Log: scx_signal_signed.h,v $
Revision 1.1  2011/08/15 17:31:11  acg
 Andy Goodrich: moved specialized signals from examples to this tree.

Revision 1.2  2011/08/15 16:43:24  acg
 Torsten Maehne: changes to remove unused argument warnings.

Revision 1.1.1.1  2006/12/15 20:20:03  acg
SystemC 2.3

Revision 1.2  2005/12/26 20:11:14  acg
Fixed up copyright.

Revision 1.1.1.1  2005/12/19 23:16:42  acg
First check in of SystemC 2.1 into its own archive.

Revision 1.17  2005/09/15 23:01:52  acg
Added std:: prefix to appropriate methods and types to get around
issues with the Edison Front End.

Revision 1.16  2005/05/03 19:52:26  acg
Get proper header locations on includes.

Revision 1.15  2005/05/03 19:50:20  acg
Name space version.

Revision 1.12  2005/04/11 19:05:36  acg
Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces

Revision 1.11  2005/04/03 22:52:52  acg
Namespace changes.

Revision 1.10  2005/03/21 22:31:32  acg
Changes to sc_core namespace.

Revision 1.9  2004/09/27 21:01:59  acg
Andy Goodrich - Forte Design Systems, Inc.
   - This is specialized signal support that allows better use of signals
     and ports whose target value is a SystemC native type.

*/



#include "sysc/utils/sc_temporary.h"
#include "sysc/communication/sc_interface.h"
#include "sysc/communication/sc_port.h"
#include "sysc/communication/sc_prim_channel.h"
#include "sysc/communication/sc_signal_ports.h"
#include "sysc/communication/sc_signal.h"
#include "sysc/kernel/sc_event.h"
#include "sysc/kernel/sc_process.h"
#include "sysc/kernel/sc_simcontext.h"
#include "sysc/kernel/sc_macros.h"
#include "sysc/tracing/sc_trace.h"
#include "sysc/datatypes/int/sc_nbdefs.h"
#include "sysc/datatypes/misc/sc_concatref.h"
#include "sysc/datatypes/int/sc_int.h"
#include "sysc/datatypes/int/sc_uint.h"
#include "sysc/datatypes/int/sc_signed.h"
#include "sysc/datatypes/int/sc_unsigned.h"
#include "sysc/datatypes/int/sc_bigint.h"
#include "sysc/datatypes/bit/sc_lv_base.h"

using sc_dt::sc_bigint;
using sc_dt::sc_bv_base;
using sc_dt::sc_lv_base;
using sc_dt::sc_concatref;
using sc_dt::sc_signed;
using sc_dt::sc_signed_subref_r;
using sc_dt::sc_unsigned;
using sc_dt::uint64;

#include <typeinfo>

/*****************************************************************************

  sc_signal_signed.h -- The sc_signal<sc_dt::sc_bigint<W> > definitions.

  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/

/* 
$Log: scx_signal_signed.h,v $
Revision 1.1  2011/08/15 17:31:11  acg
 Andy Goodrich: moved specialized signals from examples to this tree.

Revision 1.3  2011/08/15 16:43:24  acg
 Torsten Maehne: changes to remove unused argument warnings.

Revision 1.2  2011/06/28 21:23:02  acg
 Andy Goodrich: merging of SCV tree.

Revision 1.1.1.1  2006/12/15 20:20:03  acg
SystemC 2.3

Revision 1.4  2006/10/23 19:40:35  acg
 Andy Goodrich: added an explicit dynamic cast to keep gcc 4.x happy.

Revision 1.3  2006/03/21 01:31:48  acg
 Andy Goodrich: changed over to sc_get_current_process_b() from
 sc_get_current_process_base() since the function's name changed.

Revision 1.2  2005/12/26 20:11:14  acg
Fixed up copyright.

Revision 1.1.1.1  2005/12/19 23:16:42  acg
First check in of SystemC 2.1 into its own archive.

Revision 1.29  2005/09/15 23:01:52  acg
Added std:: prefix to appropriate methods and types to get around
issues with the Edison Front End.

Revision 1.28  2005/07/30 03:44:11  acg
Changes from 2.1.

Revision 1.27  2005/05/09 17:17:12  acg
Changes from 2.1.

Revision 1.26  2005/05/08 19:04:06  acg
Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.

Revision 1.25  2005/05/03 20:05:16  acg
Prefixed with sc_dt some sc_signed instances that were missed.

Revision 1.24  2005/05/03 19:50:20  acg
Name space version.

Revision 1.22  2005/03/21 22:31:32  acg
Changes to sc_core namespace.

Revision 1.21  2005/01/10 17:51:58  acg
Improvements.

Revision 1.20  2004/11/09 00:11:27  acg
Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
now is derived from sc_generic_base<sc_concatref>.

Revision 1.19  2004/09/27 21:01:59  acg
Andy Goodrich - Forte Design Systems, Inc.
   - This is specialized signal support that allows better use of signals
     and ports whose target value is a SystemC native type.

*/


#if !defined(SC_SIGNAL_SIGNED_H)
#define SC_SIGNAL_SIGNED_H

#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
#    define SC_TEMPLATE template<int W>
#else
#    define SC_TEMPLATE template<> template<int W>
#endif

// FORWARD REFERENCES AND USINGS:

using sc_dt::int64;

namespace sc_core {

class sc_signed_sigref;

//==============================================================================
// CLASS sc_signed_part_if
//
// This class provides generic access to part selections for signals whose
// data type is sc_dt::sc_bigint<W>. This class serves as the base class for the
// sc_dt::sc_bigint<W> specialization of the sc_signal_in_if<T> class. The methods
// in this class may be over-ridden individually, those that are not overridden
// will produce an error message when called. The methods are used by the 
// sc_bigint_sigref class.
//
// Notes:
//   (1) Descriptions of the methods and operators in this class appear with
//       their implementations in sc_signal<sc_dt::sc_bigint<W> >.
//==============================================================================
class sc_signed_part_if : virtual public sc_interface {
  protected:
	// constructor:
  	sc_signed_part_if() {}

  public:
    // perform a part read.
	virtual sc_dt::sc_signed* part_read_target();
  	virtual sc_dt::sc_signed read_part( int left, int right ) const;

    // perform a part write.
	virtual sc_signed_sigref& select_part( int left, int right );
    virtual void write_part( sc_dt::int64 v, int left, int right );
    virtual void write_part( sc_dt::uint64 v, int left, int right );
    virtual void write_part( const sc_dt::sc_signed& v, int left, int right );
    virtual void write_part( const sc_dt::sc_unsigned& v, int left, int right );


  private:
  	sc_signed_part_if( const sc_signed_part_if& );
  	sc_signed_part_if& operator = ( const sc_signed_part_if& );
};


//==============================================================================
// CLASS sc_signal_in_if<sc_dt::sc_bigint<W> >
//
// This is the class specializations for the sc_signal_in_if<T> class to
// provide additional features for sc_signal instances whose template is
// sc_dt::sc_bigint<W>, including part access. 
//
// Notes:
//   (1) Descriptions of the methods and operators in this class appear with
//       their implementations in sc_signal<sc_dt::sc_bigint<W> >.
//==============================================================================
template< int W >
class sc_signal_in_if<sc_dt::sc_bigint<W> > : public sc_signed_part_if {
	friend class sc_signed_sigref;
  public:
    typedef sc_signal_in_if<sc_dt::sc_bigint<W> > this_type;

    // get the value changed event
    virtual const sc_event& value_changed_event() const = 0;


    // read the current value
    virtual const sc_dt::sc_bigint<W>& read() const = 0;

    // get a reference to the current value (for tracing)
    virtual const sc_dt::sc_bigint<W>& get_data_ref() const = 0;


    // was there a value changed event?
    virtual bool event() const = 0;

  protected: 
    // constructor
    sc_signal_in_if()
    {}

  private: // disabled 
    sc_signal_in_if( const this_type& );
    this_type& operator = ( const this_type& );
};

//=============================================================================
//  CLASS : sc_signed_sigref
//
//  Proxy class for sc_signal_uint bit and part selection.
//=============================================================================
class sc_signed_sigref : public sc_dt::sc_signed_subref_r
{
  public:
    sc_signed_sigref() : sc_dt::sc_signed_subref_r() {}
    virtual ~sc_signed_sigref() {}
    virtual void concat_set(sc_dt::int64 src, int low_i);
    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
    virtual void concat_set(sc_dt::uint64 src, int low_i);

  public:
    inline void initialize( sc_signed_part_if* if_p, int left_, int right_ );

  public:
    inline void operator = ( sc_dt::uint64 v );
    inline void operator = ( const char* v );
    inline void operator = ( unsigned long v );
    inline void operator = ( long v );
    inline void operator = ( unsigned int v );
    inline void operator = ( int v );
    inline void operator = ( sc_dt::int64 v );
    inline void operator = ( double v );
    inline void operator = ( const sc_signed_sigref& v );
    template<typename T>
    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
    inline void operator = ( const sc_dt::sc_signed& v );
    inline void operator = ( const sc_dt::sc_unsigned& v );
    inline void operator = ( const sc_dt::sc_bv_base& v );
    inline void operator = ( const sc_dt::sc_lv_base& v );

  public:
    static sc_vpool<sc_signed_sigref> m_pool; // Pool of objects to use.

  protected:
    sc_signed_part_if*                m_if_p; // Target for selection.

  private:

    // disabled
    sc_signed_sigref( const sc_signed_sigref& a );
};


//==============================================================================
// CLASS sc_signal<sc_dt::sc_bigint<W> > 
//
// This class implements a signal whose value acts like an sc_dt::sc_bigint<W> data
// value. This class is a specialization of the generic sc_signal class to 
// implement tailored support for the sc_dt::sc_bigint<W> class.
//
// Notes:
//   (1) Descriptions of the methods and operators in this class appear with
//       their implementations.
//==============================================================================
SC_TEMPLATE
class sc_signal<sc_dt::sc_bigint<W> > : 
    public sc_dt::sc_bigint<W>, 
	public sc_prim_channel,
    public sc_signal_inout_if<sc_dt::sc_bigint<W> >
{
  public: // typedefs
    typedef sc_signal<sc_dt::sc_bigint<W> > this_type;

  public: // constructors and destructor:
    inline sc_signal();
    explicit inline sc_signal(const char* name_);
    virtual inline ~sc_signal();

  public: // base methods:
    inline bool base_event() const;
    inline const sc_dt::sc_bigint<W>& base_read() const;
    inline const sc_event& base_value_changed_event() const;
    inline void base_write( sc_dt::int64 value );
    inline void base_write( sc_dt::uint64 value );
    inline void base_write( const sc_dt::sc_signed& value );
    inline void base_write( const sc_dt::sc_unsigned& value );

  public: // sc_prim_channel virtual methods:
    virtual inline const char* kind() const;
    virtual inline void update();

  public: // sc_interface virtual methods:
    virtual inline const sc_event& default_event() const;
    virtual inline void register_port( 
		sc_port_base& port_, const char* if_typename_ );

  public: // sc_signed_part_if virtual methods:
    virtual inline sc_dt::sc_signed* part_read_target();
    virtual inline sc_dt::sc_signed read_part(int left, int right) const;
	virtual sc_signed_sigref& select_part( int left, int right );
	virtual inline void write_part( sc_dt::int64 v, int left, int right );
	virtual inline void write_part( sc_dt::uint64 v, int left, int right );
	virtual inline void write_part( const sc_dt::sc_signed& v, int left, int right );
	virtual inline void write_part(const sc_dt::sc_unsigned& v, int left, int right);

  public: // interface virtual methods:
    virtual inline bool event() const;
    virtual inline const sc_dt::sc_bigint<W>& get_data_ref() const;
    virtual inline sc_signal<sc_dt::sc_bigint<W> >& get_signal();
    virtual inline const sc_dt::sc_bigint<W>& read() const;
    virtual inline const sc_event& value_changed_event() const;
    virtual inline void write( const sc_in<sc_dt::sc_bigint<W> >& value );
    virtual inline void write( const sc_inout<sc_dt::sc_bigint<W> >& value );
    virtual inline void write( const sc_dt::sc_bigint<W>& value );

  public: // part selections:
  	inline sc_signed_sigref& operator () ( int left, int right );
	// #### Need to add bit() and range()
  	inline sc_signed_sigref& operator [] ( int bit );

  public: // operators:
    inline void operator = ( const this_type& new_val );
    inline void operator = ( const char* new_val );
    inline void operator = ( sc_dt::uint64 new_val );
    inline void operator = ( sc_dt::int64 new_val );
    inline void operator = ( int new_val );
    inline void operator = ( long new_val );
    inline void operator = ( short new_val );
    inline void operator = ( unsigned int new_val );
    inline void operator = ( unsigned long new_val );
    inline void operator = ( unsigned short new_val );
    template<typename T>
    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
    inline void operator = ( const sc_dt::sc_signed& new_val );
    inline void operator = ( const sc_dt::sc_unsigned& new_val );
    inline void operator = ( const sc_dt::sc_bv_base& new_val );
    inline void operator = ( const sc_dt::sc_lv_base& new_val );

    // concatenation methods (we inherit length and gets from sc_dt::sc_bigint<W>):

    virtual inline void concat_set(sc_dt::int64 src, int low_i);
    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
    virtual inline void concat_set(sc_dt::uint64 src, int low_i);

  protected: // debugging methods:
    // #### void check_port();
	void check_writer();

  private: // Disabled operations that sc_dt::sc_bigint<W> supports:
    sc_dt::sc_signed& operator ++ ();          // prefix
    const sc_dt::sc_signed& operator ++ (int); // postfix
    sc_dt::sc_signed& operator -- ();          // prefix
    const sc_dt::sc_signed& operator -- (int); // postfix
    sc_dt::sc_signed& operator += (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator += (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator += (sc_dt::int64               ); 
    sc_dt::sc_signed& operator += (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator += (long                ); 
    sc_dt::sc_signed& operator += (unsigned long       ); 
    sc_dt::sc_signed& operator += (int                 );
    sc_dt::sc_signed& operator += (unsigned int        );
    sc_dt::sc_signed& operator -= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator -= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator -= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator -= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator -= (long                ); 
    sc_dt::sc_signed& operator -= (unsigned long       ); 
    sc_dt::sc_signed& operator -= (int                 );
    sc_dt::sc_signed& operator -= (unsigned int        );
    sc_dt::sc_signed& operator *= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator *= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator *= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator *= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator *= (long                ); 
    sc_dt::sc_signed& operator *= (unsigned long       ); 
    sc_dt::sc_signed& operator *= (int                 );
    sc_dt::sc_signed& operator *= (unsigned int        );
    sc_dt::sc_signed& operator /= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator /= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator /= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator /= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator /= (long                ); 
    sc_dt::sc_signed& operator /= (unsigned long       ); 
    sc_dt::sc_signed& operator /= (int                 );
    sc_dt::sc_signed& operator /= (unsigned int        );
    sc_dt::sc_signed& operator %= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator %= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator %= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator %= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator %= (long                ); 
    sc_dt::sc_signed& operator %= (unsigned long       ); 
    sc_dt::sc_signed& operator %= (int                 );
    sc_dt::sc_signed& operator %= (unsigned int        );
    sc_dt::sc_signed& operator &= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator &= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator &= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator &= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator &= (long                ); 
    sc_dt::sc_signed& operator &= (unsigned long       ); 
    sc_dt::sc_signed& operator &= (int                 );
    sc_dt::sc_signed& operator &= (unsigned int        );
    sc_dt::sc_signed& operator |= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator |= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator |= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator |= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator |= (long                ); 
    sc_dt::sc_signed& operator |= (unsigned long       ); 
    sc_dt::sc_signed& operator |= (int                 );
    sc_dt::sc_signed& operator |= (unsigned int        );
    sc_dt::sc_signed& operator ^= (const sc_dt::sc_signed&    );
    sc_dt::sc_signed& operator ^= (const sc_dt::sc_unsigned&  );
    sc_dt::sc_signed& operator ^= (sc_dt::int64               ); 
    sc_dt::sc_signed& operator ^= (sc_dt::uint64              ); 
    sc_dt::sc_signed& operator ^= (long                ); 
    sc_dt::sc_signed& operator ^= (unsigned long       ); 
    sc_dt::sc_signed& operator ^= (int                 );
    sc_dt::sc_signed& operator ^= (unsigned int        );

  protected:
    mutable sc_event*  m_changed_event_p; // Value changed event this object.
    sc_dt::uint64      m_event_delta;     // Delta cycle of last event.
    sc_dt::sc_signed   m_new_val;         // New value for this object instance.
    sc_port_base*      m_output_p;        // Single write port verify field.
    sc_process_b*   m_writer_p;        // Single writer verify field.
};


SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
inline bool sc_signal<sc_dt::sc_bigint<W> >::base_event() const
{
    return simcontext()->delta_count() == m_event_delta + 1;
}


SC_TEMPLATE // Return this object's sc_dt::sc_bigint<W> object instance.
inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::base_read() const
{
	return *this;
}


SC_TEMPLATE // Return the value changed event, allocating it if necessary.
inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::base_value_changed_event() const
{
    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
    return *m_changed_event_p;
}


SC_TEMPLATE // Write a const sc_dt::sc_signed& value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( const sc_dt::sc_signed& value )
{
#   if defined(DEBUG_SYSTEMC)
        check_writer();
#   endif
    m_new_val = value;
    request_update();
}

SC_TEMPLATE // Write a const sc_dt::sc_unsigned& value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( const sc_dt::sc_unsigned& value )
{
#   if defined(DEBUG_SYSTEMC)
        check_writer();
#   endif
    m_new_val = value;
    request_update();
}

SC_TEMPLATE // Write a sc_dt::int64 value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( sc_dt::int64 value )
{
#   if defined(DEBUG_SYSTEMC)
        check_writer();
#   endif
    m_new_val = value;
    request_update();
}


SC_TEMPLATE // Write a sc_dt::uint64 value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::base_write( sc_dt::uint64 value )
{
#   if defined(DEBUG_SYSTEMC)
        check_writer();
#   endif
    m_new_val = value;
    request_update();
}


//------------------------------------------------------------------------------
//"sc_signal<sc_dt::sc_bigint<W> >::check_writer"
//
// This method checks to see if there is more than one writer for this 
// object instance by keeping track of the process performing the write.
//------------------------------------------------------------------------------
SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::check_writer()
{
    sc_process_b* writer_p = sc_get_current_process_b();
    if( m_writer_p == 0 ) 
    {   
        m_writer_p = writer_p;
    } 
    else if( m_writer_p != writer_p ) 
    {   
        sc_signal_invalid_writer( name(), kind(),
                                  m_writer_p->name(), writer_p->name() );
    }
}


//------------------------------------------------------------------------------
//"sc_signal<sc_dt::sc_bigint<W> >::concat_set"
//
// These virtual methods allow value assignments to this object instance
// from various sources. The position within the supplied source of the 
// low order bit for this object instance's value is low_i.
//     src   = source value.
//     low_i = bit within src to serve as low order bit of this object 
//             instance's value.
//------------------------------------------------------------------------------
SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(sc_dt::int64 src, int low_i)
{
    if ( low_i < 64 )
    {
        base_write(src >> low_i);
    }
    else
    {
        base_write( (sc_dt::int64)((src < 0 ) ?  -1 : 0 ));
    } 
}

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(
	const sc_dt::sc_lv_base& src, int low_i)
{
    sc_dt::sc_unsigned tmp(src.length());
    tmp = src >> low_i;
    base_write( tmp );
}

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(
	const sc_dt::sc_signed& src, int low_i)
{
    base_write( (src >> low_i) );
}

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(	
	const sc_dt::sc_unsigned& src, int low_i)
{
    base_write( (src >> low_i) );
}

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::concat_set(sc_dt::uint64 src, int low_i)
{
	base_write( (sc_dt::uint64)(( low_i < 64 ) ? src >> low_i : 0));
}



SC_TEMPLATE // Return the default event for this object instance.
inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::default_event() const 
	{ return base_value_changed_event(); }


SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
inline bool sc_signal<sc_dt::sc_bigint<W> >::event() const
	{ return base_event(); }


SC_TEMPLATE // Return a reference to the value of this object instance.
inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::get_data_ref() const
	{ return *this; }


SC_TEMPLATE // Return a pointer to this object instance.
inline sc_signal<sc_dt::sc_bigint<W> >& sc_signal<sc_dt::sc_bigint<W> >::get_signal() 
	{ return *this; }


SC_TEMPLATE // Return a kind value of "sc_signal".
inline const char* sc_signal<sc_dt::sc_bigint<W> >::kind() const
{
	return "sc_signal";
}


//------------------------------------------------------------------------------
//"sc_signal<sc_dt::sc_bigint<W> >::operator ()
//
// This operator returns a part selection of this object instance.
//     left  = left-hand bit of the selection.
//     right = right-hand bit of the selection.
//------------------------------------------------------------------------------
SC_TEMPLATE
inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::operator () (int left, int right)
{
    sc_signed_sigref* result_p;   // Value to return.

	result_p = sc_signed_sigref::m_pool.allocate();
	result_p->initialize(this, left, right);
	return *result_p;
}


//------------------------------------------------------------------------------
//"sc_signal<sc_dt::sc_bigint<W> >::operator []"
//
// This operator returns a bit selection of this object instance.
//     i = bit to be selected.
//------------------------------------------------------------------------------
SC_TEMPLATE
inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::operator [] ( int bit )
{
    return operator () (bit,bit);
}


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const this_type& new_val )
	{ base_write( new_val ); }

SC_TEMPLATE 
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const char* new_val )
	{ sc_dt::sc_bigint<W> tmp = new_val; m_new_val = tmp; request_update(); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( sc_dt::uint64 new_val )
	{ base_write(new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( sc_dt::int64 new_val )
	{ base_write(new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( int new_val )
	{ base_write((sc_dt::int64)new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( long new_val ) 
	{ base_write((sc_dt::int64)new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( short new_val ) 
	{ base_write((sc_dt::int64)new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned int new_val ) 
	{ base_write((sc_dt::int64)new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned long new_val )
	{ base_write((sc_dt::int64)new_val); }


SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( unsigned short new_val )
	{ base_write((sc_dt::int64)new_val); }

SC_TEMPLATE
template<typename T>
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = (
    const sc_dt::sc_generic_base<T>& new_val )
{
    sc_dt::sc_unsigned temp(W);
    new_val->to_sc_unsigned(temp);
    base_write(temp);
}

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
	{ base_write(new_val); }

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
	{ base_write( (sc_dt::sc_bigint<W>)new_val ); }

SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
	{ base_write( (sc_dt::sc_bigint<W>)new_val ); }



SC_TEMPLATE
inline void sc_signal<sc_dt::sc_bigint<W> >::operator = ( const sc_dt::sc_signed& new_val )
	{ base_write(new_val); }


SC_TEMPLATE // Return a pointer to the read target for part selections.
inline sc_dt::sc_signed* sc_signal<sc_dt::sc_bigint<W> >::part_read_target()
	{ return this; }

SC_TEMPLATE // Return this object's base value as a const reference.
inline const sc_dt::sc_bigint<W>& sc_signal<sc_dt::sc_bigint<W> >::read() const
	{ return *this; }


SC_TEMPLATE // Read a portion of a value.
inline sc_dt::sc_signed sc_signal<sc_dt::sc_bigint<W> >::read_part( 
	int left, int right ) const
{
    return (sc_dt::sc_signed)sc_dt::sc_signed::operator () (left, right);
}

SC_TEMPLATE // Register a port for write checking.
inline void sc_signal<sc_dt::sc_bigint<W> >::register_port( 
	sc_port_base& port_, const char* if_typename_ )
{
#       ifdef DEBUG_SYSTEMC
		std::string nm( if_typename_ );
		if( nm == typeid( sc_signal_inout_if<sc_dt::sc_bigint<W> > ).name() ) 
		{
			if( m_output_p != 0 ) 
			{
				sc_signal_invalid_writer( name(), kind(),
					 m_output_p->name(), port_.name() );
			}
			m_output_p = &port_;
		}
#       else
            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
#       endif
}


SC_TEMPLATE // Autogenerated name object instance constructor.
inline sc_signal<sc_dt::sc_bigint<W> >::sc_signal() : 
	sc_prim_channel(sc_gen_unique_name( "signal" )),
	m_changed_event_p(0),
	m_new_val(W),
	m_output_p(0),
	m_writer_p(0)
{ }


SC_TEMPLATE // Explicitly named object instance constructor.
inline sc_signal<sc_dt::sc_bigint<W> >::sc_signal(const char* name_) : 
	sc_prim_channel(name_),
	m_changed_event_p(0),
	m_new_val(W),
	m_output_p(0),
	m_writer_p(0)
{ }


SC_TEMPLATE // Object instance destructor.
inline sc_signal<sc_dt::sc_bigint<W> >::~sc_signal() 
{
	if ( m_changed_event_p ) delete m_changed_event_p;
}


SC_TEMPLATE // Update the current value from new value.
inline void sc_signal<sc_dt::sc_bigint<W> >::update()
{
    if ( m_changed_event_p )
    {
        if ( m_new_val != *this )
        {
            m_changed_event_p->notify_delayed();
            m_event_delta = simcontext()->delta_count();
        }
    }
	sc_dt::sc_signed::operator = (m_new_val);
}


SC_TEMPLATE // Return the value changed event.
inline const sc_event& sc_signal<sc_dt::sc_bigint<W> >::value_changed_event() const
	{ return base_value_changed_event(); }


SC_TEMPLATE // Write a sc_in<sc_dt::sc_bigint<W> > value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_in<sc_dt::sc_bigint<W> >& value )
	{ base_write( value ); }


SC_TEMPLATE // Write a sc_inout<sc_dt::sc_bigint<W> > value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_inout<sc_dt::sc_bigint<W> >& value ) 
	{ base_write( value ); }


SC_TEMPLATE // Write a sc_dt::sc_bigint<W> value to this object instance.
inline void sc_signal<sc_dt::sc_bigint<W> >::write( const sc_dt::sc_bigint<W>& value ) 
	{ base_write( value); }


SC_TEMPLATE // Select a portion of a value. 
inline sc_signed_sigref& sc_signal<sc_dt::sc_bigint<W> >::select_part(
    int left, int right)
{
    sc_signed_sigref* result_p = sc_signed_sigref::m_pool.allocate();
    result_p->initialize(DCAST<sc_signed_part_if*>(this), left, right);
    return *result_p;
}


SC_TEMPLATE // Write a portion of a value. If this is the first write in 
            // a delta cycle we copy the existing value before setting the bits.
inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(sc_dt::int64 v, int left, int right) 
{
	m_new_val(left, right) = v;
	request_update();
}


SC_TEMPLATE // Write a portion of a value. If this is the first write in 
            // a delta cycle we copy the existing value before setting the bits.
inline void sc_signal<sc_dt::sc_bigint<W> >::write_part(sc_dt::uint64 v, int left, int right)
{
	m_new_val(left, right) = v;
	request_update();
}


SC_TEMPLATE // Write a portion of a value. If this is the first write in 
            // a delta cycle we copy the existing value before setting the bits.
inline void sc_signal<sc_dt::sc_bigint<W> >::write_part( 
	const sc_dt::sc_signed& v, int left, int right ) 
{
	m_new_val(left, right) = v;
	request_update();
}


SC_TEMPLATE // Write a portion of a value. If this is the first write in 
            // a delta cycle we copy the existing value before setting the bits.
inline void sc_signal<sc_dt::sc_bigint<W> >::write_part( 
	const sc_dt::sc_unsigned& v, int left, int right ) 
{
	m_new_val(left, right) = v;
	request_update();
}


//==============================================================================
// CLASS sc_in<sc_dt::sc_bigint<W> >
//
// This class implements an input port whose target acts like an sc_dt::sc_bigint<W> data
// value. This class is a specialization of the generic sc_in class to 
// implement tailored support for the sc_dt::sc_bigint<W> class.
//==============================================================================
SC_TEMPLATE
class sc_in<sc_dt::sc_bigint<W> > : 
    public sc_port<sc_signal_in_if<sc_dt::sc_bigint<W> >, 1, 
                   SC_ONE_OR_MORE_BOUND>,
    public sc_dt::sc_value_base
{
  public:

    // typedefs

    typedef sc_dt::sc_bigint<W>                      data_type;
    typedef sc_signal_in_if<sc_dt::sc_bigint<W> >    if_type;
    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>  base_type;
    typedef sc_in<sc_dt::sc_bigint<W> >              this_type;

    typedef if_type                                  in_if_type;
    typedef base_type                                in_port_type;
    typedef sc_signal_inout_if<sc_dt::sc_bigint<W> > inout_if_type;
    typedef sc_inout<sc_dt::sc_bigint<W> >           inout_port_type;

  public:

    // bind methods and operators:

    void bind( const in_if_type& interface_ ) 
        { sc_port_base::bind( CCAST<in_if_type&>( interface_) );}
    void operator () ( const in_if_type& interface_ )
        { sc_port_base::bind( CCAST<in_if_type&>( interface_) );}
    void bind( in_port_type& parent_ )
        { sc_port_base::bind(parent_);}
    void operator () ( in_port_type& parent_ )
        { sc_port_base::bind(parent_);}
    void bind( inout_port_type& parent_ )
        { sc_port_base::bind(parent_);}
    void operator () ( inout_port_type& parent_ )
        { sc_port_base::bind(parent_);}

  protected:
    // called by pbind (for internal use only)
    virtual inline int vbind( sc_interface& interface_ )
        {
            return sc_port_b<if_type>::vbind( interface_ );
        }       
    virtual inline int vbind( sc_port_base& parent_ )
        {
            in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );  
            if( in_parent != 0 ) {
                sc_port_base::bind( *in_parent );
                return 0;
            }
            inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
            if( inout_parent != 0 ) {
                sc_port_base::bind( *inout_parent );
                return 0;
            }
            // type mismatch
            return 2;     
        }


    // constructors

  public:
    sc_in()
        : base_type(), m_traces( 0 )
        {}

    explicit sc_in( const char* name_ )
        : base_type( name_ ), m_traces( 0 )
        {}

    explicit sc_in( const in_if_type& interface_ )
        : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 )
        {}

    sc_in( const char* name_, const in_if_type& interface_ )     
        : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 )
        {}

    explicit sc_in( in_port_type& parent_ )
        : base_type( parent_ ), m_traces( 0 )
        {}

    sc_in( const char* name_, in_port_type& parent_ )
        : base_type( name_, parent_ ), m_traces( 0 )  
        {}

    explicit sc_in( inout_port_type& parent_ )
        : base_type(), m_traces( 0 )
        { sc_port_base::bind( parent_ ); }

    sc_in( const char* name_, inout_port_type& parent_ )
        : base_type( name_ ), m_traces( 0 )
        { sc_port_base::bind( parent_ ); }

    sc_in( this_type& parent_ )
        : base_type( parent_ ), m_traces( 0 )
        {}

    sc_in( const char* name_, this_type& parent_ )
        : base_type( name_, parent_ ), m_traces( 0 )
        {}


    // destructor

    virtual inline ~sc_in()
        {
            remove_traces();
        }

    // bit and part selection

    sc_dt::sc_signed_bitref_r operator [] ( int i ) const
        { return (*this)->read()[i]; }
    sc_dt::sc_signed_bitref_r bit( int i ) const
        { return (*this)->read()[i]; }
    sc_dt::sc_signed_subref_r operator () ( int left, int right ) const
        { return (*this)->read()(left,right); }
    sc_dt::sc_signed_subref_r range( int left, int right ) const
        { return (*this)->read()(left,right); }


    // interface access shortcut methods

    // get the default event

    const sc_event& default_event() const
        { return (*this)->value_changed_event(); }


    // get the value changed event

    const sc_event& value_changed_event() const
        { return (*this)->value_changed_event(); }


    // read the current value

    const sc_dt::sc_bigint<W>& read() const
        { return (*this)->read(); }

    operator const sc_dt::sc_bigint<W>& () const
        { return (*this)->read(); }

    // was there a value changed event?

    bool event() const
        { return (*this)->event(); }


    // (other) event finder method(s)

    sc_event_finder& value_changed() const
        {
            return *new sc_event_finder_t<in_if_type>(
                *this, &in_if_type::value_changed_event );
        }



    // reduction methods:

    inline bool and_reduce() const
        { return (*this)->read().and_reduce(); }
    inline bool nand_reduce() const
        { return (*this)->read().nand_reduce(); }
    inline bool nor_reduce() const
        { return (*this)->read().nor_reduce(); }
    inline bool or_reduce() const
        { return (*this)->read().or_reduce(); }
    inline bool xnor_reduce() const
        { return (*this)->read().xnor_reduce(); }
    inline bool xor_reduce() const
        { return (*this)->read().xor_reduce(); }


    // called when elaboration is done
    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */

    virtual inline void end_of_elaboration()
        {
            if( m_traces != 0 ) {
                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
                    sc_trace_params* p = (*m_traces)[i];
                    sc_trace( p->tf, read(), p->name );
                }
                remove_traces();
            }
        }

    virtual inline const char* kind() const 
        { return "sc_in"; }


    // called by sc_trace
    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
        { 
            if( tf_ != 0 ) {
                if( m_traces == 0 ) {
                    m_traces = new sc_trace_params_vec;
                }
                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
            }
        }


    // concatenation methods

    virtual inline int concat_length(bool* xz_present_p) const
        { return (*this)->read().concat_length( xz_present_p ); }
    virtual inline sc_dt::uint64 concat_get_uint64() const
        { return (*this)->read().concat_get_uint64(); }
    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
        { return (*this)->read().concat_get_data(dst_p, low_i); }

  protected:
    void remove_traces() const
        {
            if( m_traces != 0 ) {
                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
                    delete (*m_traces)[i];
                }
                delete m_traces;
                m_traces = 0;
            }
        }

    mutable sc_trace_params_vec* m_traces;


  private:

    // disabled
    sc_in( const sc_in<sc_dt::sc_bigint<W> >& );
    sc_in<sc_dt::sc_bigint<W> >& operator = ( const sc_in<sc_dt::sc_bigint<W> >& );

#ifdef __GNUC__
    // Needed to circumvent a problem in the g++-2.95.2 compiler:
    // This unused variable forces the compiler to instantiate
    // an object of T template so an implicit conversion from
    // read() to a C++ intrinsic data type will work.
    static data_type dummy;
#endif

};



SC_TEMPLATE
inline std::ostream& operator << ( 
	std::ostream& os, const sc_in<sc_dt::sc_bigint<W> >& a )
{
    a.read().print( os );
    return os;
}


//==============================================================================
// CLASS sc_inout<sc_dt::sc_bigint<W> >
//
// This class implements an input/output port whose target acts like an 
// sc_dt::sc_bigint<W> data value. It is derived from the sc_signed_in. This class is a 
// specialization of the generic sc_inout class to implement tailored support 
// for the sc_dt::sc_bigint<W> class.
//==============================================================================
SC_TEMPLATE
class sc_inout<sc_dt::sc_bigint<W> > : 
    public sc_port<sc_signal_inout_if<sc_dt::sc_bigint<W> >, 1,
                   SC_ONE_OR_MORE_BOUND>,
    public sc_dt::sc_value_base
{
  public:

    // typedefs

    typedef sc_dt::sc_bigint<W>                      data_type;
    typedef sc_signal_inout_if<sc_dt::sc_bigint<W> > if_type;
    typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND>  base_type;
    typedef sc_inout<sc_dt::sc_bigint<W> >           this_type;

    typedef if_type                                  inout_if_type;
    typedef base_type                                inout_port_type;

  public:

    // bind methods and operators:

    void bind( const inout_if_type& interface_ ) 
        { sc_port_base::bind( CCAST<inout_if_type&>( interface_) ); }
    void operator () ( const inout_if_type& interface_ )
        { sc_port_base::bind( CCAST<inout_if_type&>( interface_) ); }
    void bind( inout_port_type& parent_ )
        { sc_port_base::bind(parent_); }
    void operator () ( inout_port_type& parent_ )
        { sc_port_base::bind(parent_); }

  protected:
    // called by pbind (for internal use only)
    virtual inline int vbind( sc_interface& interface_ )
        {
            return sc_port_b<if_type>::vbind( interface_ );
        }       
    virtual inline int vbind( sc_port_base& parent_ )
        {
            inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
            if( inout_parent != 0 ) {
                sc_port_base::bind( *inout_parent );
                return 0;
            }
            // type mismatch
            return 2;     
        }


    // constructors

  public:
    sc_inout()
        : base_type(), m_init_val_p(0), m_traces( 0 )
        {}

    explicit sc_inout( const char* name_ )
        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
        {}

    explicit sc_inout( inout_if_type& interface_ )
        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
        {}

    sc_inout( const char* name_, inout_if_type& interface_ )     
        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
        {}

    explicit sc_inout( inout_port_type& parent_ )
        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
        {}

    sc_inout( const char* name_, inout_port_type& parent_ )
        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )  
        {}

    sc_inout( this_type& parent_ )
        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
        {}

    sc_inout( const char* name_, this_type& parent_ )
        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
        {}


    // destructor

    virtual inline ~sc_inout()
        {
            remove_traces();
        }

    // bit and part selection

    sc_dt::sc_signed_bitref_r operator [] ( int i ) const
        { return (*this)->read()[i]; }
    sc_dt::sc_signed_bitref_r bit( int i ) const
        { return (*this)->read()[i]; }
    sc_signed_sigref& operator [] ( int i ) 
		{ return (*this)->select_part(i,i); }
    sc_signed_sigref& bit( int i ) 
		{ return (*this)->select_part(i,i); }
    sc_dt::sc_signed_subref_r operator () ( int left, int right ) const
        { return (*this)->read()(left,right); }
    sc_dt::sc_signed_subref_r range( int left, int right ) const
        { return (*this)->read()(left,right); }
    sc_signed_sigref& operator () ( int left, int right )
		{ return (*this)->select_part(left,right); }
    sc_signed_sigref& range( int left, int right )
		{ return (*this)->select_part(left,right); }


    // interface access shortcut methods

    // get the default event

    const sc_event& default_event() const
        { return (*this)->value_changed_event(); }


    // get the value changed event

    const sc_event& value_changed_event() const
        { return (*this)->value_changed_event(); }


    // read the current value

    const sc_dt::sc_bigint<W>& read() const
        { return (*this)->read(); }

    operator const sc_dt::sc_bigint<W>& () const
        { return (*this)->read(); }

    // was there a value changed event?

    bool event() const
        { return (*this)->event(); }


    // (other) event finder method(s)

    sc_event_finder& value_changed() const
        {
            return *new sc_event_finder_t<inout_if_type>(
                *this, &inout_if_type::value_changed_event );
        }



    // reduction methods:

    inline bool and_reduce() const
        { return (*this)->read().and_reduce(); }
    inline bool nand_reduce() const
        { return (*this)->read().nand_reduce(); }
    inline bool nor_reduce() const
        { return (*this)->read().nor_reduce(); }
    inline bool or_reduce() const
        { return (*this)->read().or_reduce(); }
    inline bool xnor_reduce() const
        { return (*this)->read().xnor_reduce(); }
    inline bool xor_reduce() const
        { return (*this)->read().xor_reduce(); }


    // called when elaboration is done
    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */

    virtual inline void end_of_elaboration()
        {
            if( m_init_val_p != 0 ) {
                (*this)->write( *m_init_val_p );
                delete m_init_val_p;
                m_init_val_p = 0;
            }
            if( m_traces != 0 ) {
                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
                    sc_trace_params* p = (*m_traces)[i];
                    sc_trace( p->tf, read(), p->name );
                }
                remove_traces();
            }
        }

    virtual inline const char* kind() const 
        { return "sc_inout"; }

    // value initialization

    inline void initialize( const sc_dt::sc_bigint<W>& value_ )
    {
        inout_if_type* iface = DCAST<inout_if_type*>( this->get_interface() );     
        if( iface != 0 ) {
            iface->write( value_ );
        } else {
            if( m_init_val_p == 0 ) {
                m_init_val_p = new sc_dt::sc_bigint<W>;
            }
            *m_init_val_p = value_;
        }
    }


    // called by sc_trace
    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
        { 
            if( tf_ != 0 ) {
                if( m_traces == 0 ) {
                    m_traces = new sc_trace_params_vec;
                }
                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
            }
        }


    // concatenation methods

    virtual inline int concat_length(bool* xz_present_p) const
        { return (*this)->read().concat_length( xz_present_p ); }
    virtual inline sc_dt::uint64 concat_get_uint64() const
        { return (*this)->read().concat_get_uint64(); }
    virtual inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
    virtual inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
        { return (*this)->read().concat_get_data(dst_p, low_i); }
    virtual inline void concat_set(sc_dt::int64 src, int low_i)
		{ *this = (src >> ((low_i < 64) ? low_i : 63)); }
#if 0 // ####
    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
        { *this = src >> low_i; }
#endif // 0 ####
    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
        { *this = (src >> low_i); }
    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
        { *this = (src >> low_i); }
    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
        { *this = ((low_i < 64) ? (src >> low_i) : (sc_dt::uint64)0); }


  public: // assignment operators:
    inline void operator = ( const this_type& new_val )
        { (*this)->write( new_val.read() ); }
    inline void operator = ( const char* new_val )
        { sc_dt::sc_signed aa(W); aa = new_val; (*this)->write( aa ); }
    inline void operator = ( sc_dt::uint64 new_val )
        { (*this)->write(new_val); }
    inline void operator = ( sc_dt::int64 new_val )
        { (*this)->write(new_val); }
    inline void operator = ( int new_val )
        { (*this)->write((sc_dt::int64)new_val); }
    inline void operator = ( long new_val )
        { (*this)->write((sc_dt::int64)new_val); }
    inline void operator = ( short new_val )
        { (*this)->write((sc_dt::int64)new_val); }
    inline void operator = ( unsigned int new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( unsigned long new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( unsigned short new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    template<typename T>
    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
        {
            sc_dt::sc_unsigned temp(W);
            new_val->to_sc_unsigned(temp);
            (*this)->write(temp);
        }
    inline void operator = ( const sc_dt::sc_signed& new_val )
        { (*this)->write(new_val); }
    inline void operator = ( const sc_dt::sc_unsigned& new_val )
        { (*this)->write(new_val); }
    inline void operator = ( const sc_dt::sc_bv_base& new_val )
        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
    inline void operator = ( const sc_dt::sc_lv_base& new_val )
        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }

    inline void write( const sc_in<sc_dt::sc_bigint<W> >& new_val )
        { (*this)->write( new_val.read() ); }
    inline void write( const sc_inout<sc_dt::sc_bigint<W> >& new_val )
        { (*this)->write( new_val.read() ); }
    inline void write( const sc_dt::sc_bigint<W>& new_val )
        { (*this)->write( new_val); }

  protected:
    void remove_traces() const
        {
            if( m_traces != 0 ) {
                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
                    delete (*m_traces)[i];
                }
                delete m_traces;
                m_traces = 0;
            }
        }

    sc_dt::sc_bigint<W>*                m_init_val_p;
    mutable sc_trace_params_vec* m_traces;


  private:

    // disabled
    sc_inout( const sc_inout<sc_dt::sc_bigint<W> >& );

#ifdef __GNUC__
    // Needed to circumvent a problem in the g++-2.95.2 compiler:
    // This unused variable forces the compiler to instantiate
    // an object of T template so an implicit conversion from
    // read() to a C++ intrinsic data type will work.
    static data_type dummy;
#endif

};



SC_TEMPLATE
inline std::ostream& operator << ( 
	std::ostream& os, const sc_inout<sc_dt::sc_bigint<W> >& a )
{
    a.read().print( os );
    return os;
}


//==============================================================================
// CLASS sc_out<sc_dt::sc_bigint<W> >
//
// This class implements an output port whose target acts like an 
// sc_dt::sc_bigint<W> data value. This class is a derivation of sc_inout, since
// output ports are really no different from input/output ports.
//==============================================================================
SC_TEMPLATE
class sc_out<sc_dt::sc_bigint<W> > : public sc_inout<sc_dt::sc_bigint<W> >
{
  public:

    // typedefs

    typedef sc_dt::sc_bigint<W>                          data_type;

    typedef sc_out<data_type>                   this_type;
    typedef sc_inout<data_type>                 base_type;

    typedef typename base_type::inout_if_type   inout_if_type;
    typedef typename base_type::inout_port_type inout_port_type;

    // constructors

    sc_out()
        : base_type()
        {}

    explicit sc_out( const char* name_ )
        : base_type( name_ )
        {}

    explicit sc_out( inout_if_type& interface_ )
        : base_type( interface_ )
        {}

    sc_out( const char* name_, inout_if_type& interface_ )
        : base_type( name_, interface_ )
        {}

    explicit sc_out( inout_port_type& parent_ )
        : base_type( parent_ )
        {}

    sc_out( const char* name_, inout_port_type& parent_ )
        : base_type( name_, parent_ )
        {}

    sc_out( this_type& parent_ )
        : base_type( parent_ )
        {}

    sc_out( const char* name_, this_type& parent_ )
        : base_type( name_, parent_ )
        {}


    // destructor (does nothing)

    virtual inline ~sc_out()
        {}


    // assignment operators:

  public:
    inline void operator = ( const this_type& new_val )
        { (*this)->write( (const sc_dt::sc_signed&)new_val ); }
    inline void operator = ( const char* new_val )
        { sc_dt::sc_signed aa(W); aa = new_val; (*this)->write( aa ); }
    inline void operator = ( sc_dt::uint64 new_val )
        { (*this)->write(new_val); }
    inline void operator = ( sc_dt::int64 new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( int new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( long new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( short new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( unsigned int new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( unsigned long new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    inline void operator = ( unsigned short new_val )
        { (*this)->write((sc_dt::uint64)new_val); }
    template<typename T>
    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
        {
            sc_dt::sc_unsigned temp(W);
            new_val->to_sc_unsigned(temp);
            (*this)->write(temp);
        }
    inline void operator = ( const sc_dt::sc_signed& new_val )
        { (*this)->write(new_val); }
    inline void operator = ( const sc_dt::sc_unsigned& new_val )
        { (*this)->write(new_val); }
    inline void operator = ( const sc_dt::sc_bv_base& new_val )
        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }
    inline void operator = ( const sc_dt::sc_lv_base& new_val )
        { (*this)->write((sc_dt::sc_bigint<W>)new_val); }

  private:

    // disabled
    sc_out( const this_type& );
};



//------------------------------------------------------------------------------
//"sc_signed_sigref::initialize"
//
// This method initializes an object instance from the supplied arguments.
//     if_p   -> target of this selection.
//     left_  =  left-most bit in selection.
//     right_ =  right-most bit in selection.
//------------------------------------------------------------------------------
inline void sc_signed_sigref::initialize( 
	sc_signed_part_if* if_p, int left_, int right_ )
{
    m_if_p = if_p;
    m_left = left_;
    m_right = right_;
	m_obj_p = if_p->part_read_target();
}


//------------------------------------------------------------------------------
//"sc_signed_sigref::operator ="
//
// These operators assign a value to the bits associated with this object
// instance within this object instance's target signal.
//------------------------------------------------------------------------------
inline void sc_signed_sigref::operator = ( sc_dt::uint64 v )
{
	m_if_p->write_part( v, m_left, m_right );
}

inline void sc_signed_sigref::operator = ( const char* v )
{
	sc_dt::sc_signed tmp(length()); tmp = v; *this = tmp;
}

inline void sc_signed_sigref:: operator = ( sc_dt::int64 v )
{ 
    *this = (sc_dt::uint64)v; 
}

inline void sc_signed_sigref:: operator = ( int v )
{ 
    *this = (sc_dt::uint64)v; 
}

inline void sc_signed_sigref:: operator = ( long v )
{ 
    *this = (sc_dt::uint64)v; 
}

inline void sc_signed_sigref:: operator = ( unsigned int v )
{ 
    *this = (sc_dt::uint64)v; 
}

inline void sc_signed_sigref:: operator = ( unsigned long v )
{ 
    *this = (sc_dt::uint64)v; 
}

template<typename T>
inline void sc_signed_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v )
{
    sc_dt::sc_unsigned temp(m_left-m_right+1);
    v->to_sc_unsigned(temp);
    m_if_p->write_part( temp, m_left, m_right );
}

inline void sc_signed_sigref:: operator = ( const sc_dt::sc_signed& v )
{ 
    m_if_p->write_part( v, m_left, m_right );
}

inline void sc_signed_sigref:: operator = ( const sc_dt::sc_unsigned& v )
{ 
    m_if_p->write_part( v, m_left, m_right );
}

void sc_signed_sigref::operator = ( const sc_signed_sigref& v )
{
    *this = (sc_dt::sc_unsigned)v;
}


#undef SC_TEMPLATE
} // namespace sc_core
#endif // !defined(SC_SIGNAL_SIGNED_H)

namespace sc_core {

extern
void
sc_signal_invalid_writer( const char* name,
                          const char* kind,
                          const char* first_writer,
                          const char* second_writer );

//------------------------------------------------------------------------------
// POOL OF TEMPORARY INSTANCES OF sc_signed_sigref
//
// This allows use to pass const references for part and bit selections
// on sc_signal_signed object instances.
//------------------------------------------------------------------------------
sc_vpool<sc_signed_sigref> sc_signed_sigref::m_pool(8);


//------------------------------------------------------------------------------
//"sc_signed_part_if::default methods"
//
// These versions just produce errors if they are not overloaded but used.
//------------------------------------------------------------------------------

sc_signed* sc_signed_part_if::part_read_target()
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
    return 0;
}
sc_signed sc_signed_part_if::read_part( int /*left*/, int /*right*/ ) const
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
    return sc_signed(1);
}
sc_signed_sigref& sc_signed_part_if::select_part( int /*left*/, int /*right*/ )
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
    return *(sc_signed_sigref*)0;
}
void sc_signed_part_if::write_part( int64 v, int /*left*/, int /*right*/ )
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
}
void sc_signed_part_if::write_part( uint64 v, int /*left*/, int /*right*/ )
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
}
void sc_signed_part_if::write_part(     
    const sc_signed& v, int /*left*/, int /*right*/ )
{ 
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
}   
void sc_signed_part_if::write_part(
    const sc_unsigned& v, int /*left*/, int /*right*/ )
{
    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
}


//------------------------------------------------------------------------------
//"sc_signed_sigref::concate_set"
//
// These methods assign this object instance's value from the supplied
// value starting at the supplied bit within that value.
//     src = value to use to set this object instance's value.
//     low_i = bit in src that is to be the low order bit of the value to set.
// #### OPTIMIZE
//------------------------------------------------------------------------------
void sc_signed_sigref::concat_set(sc_dt::int64 src, int low_i)
{
	int64 tmp;
	if ( low_i < 63 ) 
		tmp = src >> low_i;
	else
		tmp = (src < 0) ? -1 : 0;
	m_if_p->write_part( tmp, m_left, m_right );
}


void sc_signed_sigref::concat_set(const sc_signed& src, int low_i)
{
	m_if_p->write_part( src >> low_i, m_left, m_right );
}


void sc_signed_sigref::concat_set(const sc_lv_base& src, int low_i)
{
	sc_unsigned tmp(src.length());
	tmp = src;
	m_if_p->write_part( tmp >> low_i, m_left, m_right );
}


void sc_signed_sigref::concat_set(const sc_unsigned& src, int low_i)
{
	m_if_p->write_part( src >> low_i, m_left, m_right );
}


void sc_signed_sigref::concat_set(sc_dt::uint64 src, int low_i)
{
	uint64 tmp = (low_i < 63) ? (src >> low_i) : 0;
	m_if_p->write_part( tmp, m_left, m_right );
}

} // namespace sc_core
