1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_signal_int.cpp -- The sc_signal<sc_dt::sc_int<W> > implementations.
23
24  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38/*
39$Log: scx_signal_int.h,v $
40Revision 1.1  2011/08/15 17:31:11  acg
41 Andy Goodrich: moved specialized signals from examples to this tree.
42
43Revision 1.2  2011/08/15 16:43:24  acg
44 Torsten Maehne: changes to remove unused argument warnings.
45
46Revision 1.1.1.1  2006/12/15 20:20:03  acg
47SystemC 2.3
48
49Revision 1.2  2005/12/26 20:11:14  acg
50Fixed up copyright.
51
52Revision 1.1.1.1  2005/12/19 23:16:42  acg
53First check in of SystemC 2.1 into its own archive.
54
55Revision 1.11  2005/04/11 19:05:36  acg
56Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces
57
58Revision 1.10  2005/04/03 22:52:51  acg
59Namespace changes.
60
61Revision 1.9  2005/03/21 22:31:32  acg
62Changes to sc_core namespace.
63
64Revision 1.8  2004/09/27 21:01:59  acg
65Andy Goodrich - Forte Design Systems, Inc.
66   - This is specialized signal support that allows better use of signals
67     and ports whose target value is a SystemC native type.
68
69*/
70
71
72
73#include <systemc>
74#include <typeinfo>
75
76/*****************************************************************************
77
78  sc_signal_uint.h -- The sc_signal<sc_dt::sc_int<W> > definitions.
79
80  Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22
81
82 *****************************************************************************/
83
84/*****************************************************************************
85
86  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
87  changes you are making here.
88
89      Name, Affiliation, Date:
90  Description of Modification:
91
92 *****************************************************************************/
93
94/*
95$Log: scx_signal_int.h,v $
96Revision 1.1  2011/08/15 17:31:11  acg
97 Andy Goodrich: moved specialized signals from examples to this tree.
98
99Revision 1.3  2011/08/15 16:43:24  acg
100 Torsten Maehne: changes to remove unused argument warnings.
101
102Revision 1.2  2011/06/28 21:23:02  acg
103 Andy Goodrich: merging of SCV tree.
104
105Revision 1.1.1.1  2006/12/15 20:20:03  acg
106SystemC 2.3
107
108Revision 1.2  2005/12/26 20:11:14  acg
109Fixed up copyright.
110
111Revision 1.1.1.1  2005/12/19 23:16:42  acg
112First check in of SystemC 2.1 into its own archive.
113
114Revision 1.21  2005/03/21 22:31:32  acg
115Changes to sc_core namespace.
116
117Revision 1.20  2005/01/10 17:51:58  acg
118Improvements.
119
120Revision 1.19  2004/11/09 00:11:26  acg
121Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref
122now is derived from sc_generic_base<sc_concatref>.
123
124Revision 1.18  2004/09/27 21:01:59  acg
125Andy Goodrich - Forte Design Systems, Inc.
126   - This is specialized signal support that allows better use of signals
127     and ports whose target value is a SystemC native type.
128
129*/
130
131
132#if !defined(SC_SIGNAL_INT_H)
133#define SC_SIGNAL_INT_H
134
135#if ( !defined(_MSC_VER) || _MSC_VER > 1200 )
136#    define SC_TEMPLATE template<int W>
137#else
138#    define SC_TEMPLATE template<> template<int W>
139#endif
140
141
142// FORWARD REFERENCES AND USINGS:
143
144
145namespace sc_core {
146
147class sc_int_sigref;
148
149//==============================================================================
150// CLASS sc_int_part_if
151//
152// This class provides generic access to part selections for signals whose
153// data type is sc_dt::sc_int<W>. This class serves as the base class for the
154// sc_dt::sc_int<W> specialization of the sc_signal_in_if<T> class. The methods
155// in this class may be over-ridden individually, those that are not overridden
156// will produce an error message when called. The methods are used by the
157// sc_int_sigref class.
158//
159// Notes:
160//   (1) Descriptions of the methods and operators in this class appear with
161//       their implementations in sc_signal<sc_dt::sc_int<W> >.
162//==============================================================================
163class sc_int_part_if : virtual public sc_interface {
164  protected:
165	// constructor:
166  	sc_int_part_if() {}
167
168  public:
169    // perform a part read.
170	virtual sc_dt::sc_int_base* part_read_target();
171  	virtual sc_dt::uint64 read_part( int left, int right ) const;
172
173    // perform a part write.
174	virtual sc_int_sigref& select_part( int left, int right );
175  	virtual void write_part( sc_dt::uint64 v, int left, int right );
176
177  private:
178  	sc_int_part_if( const sc_int_part_if& );
179  	sc_int_part_if& operator = ( const sc_int_part_if& );
180};
181
182
183//==============================================================================
184// CLASS sc_signal_in_if<sc_dt::sc_int<W> >
185//
186// This is the class specializations for the sc_signal_in_if<T> class to
187// provide additional features for sc_signal instances whose template is
188// sc_dt::sc_int<W>, including part access.
189//
190// Notes:
191//   (1) Descriptions of the methods and operators in this class appear with
192//       their implementations in sc_signal<sc_dt::sc_int<W> >.
193//==============================================================================
194template< int W >
195class sc_signal_in_if<sc_dt::sc_int<W> > : public sc_int_part_if {
196	friend class sc_int_sigref;
197  public:
198    typedef sc_signal_in_if<sc_dt::sc_int<W> > this_type;
199
200    // get the value changed event
201    virtual const sc_event& value_changed_event() const = 0;
202
203
204    // read the current value
205    virtual const sc_dt::sc_int<W>& read() const = 0;
206
207    // get a reference to the current value (for tracing)
208    virtual const sc_dt::sc_int<W>& get_data_ref() const = 0;
209
210
211    // was there a value changed event?
212    virtual bool event() const = 0;
213
214  protected:
215    // constructor
216    sc_signal_in_if()
217    {}
218
219  private: // disabled
220    sc_signal_in_if( const this_type& );
221    this_type& operator = ( const this_type& );
222};
223
224//=============================================================================
225//  CLASS : sc_int_sigref
226//
227//  Proxy class for sc_signal_int bit and part selection.
228//=============================================================================
229class sc_int_sigref : public sc_dt::sc_int_subref_r
230{
231  public:
232    sc_int_sigref() : sc_dt::sc_int_subref_r() {}
233    virtual ~sc_int_sigref() {}
234    virtual void concat_set(sc_dt::int64 src, int low_i);
235    virtual void concat_set(const sc_dt::sc_signed& src, int low_i);
236    virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i);
237    virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i);
238    virtual void concat_set(sc_dt::uint64 src, int low_i);
239
240  public:
241    inline void initialize( sc_int_part_if* if_p, int left_, int right_ );
242
243  public:
244    inline void operator = ( sc_dt::uint64 v );
245    inline void operator = ( const char* v );
246    inline void operator = ( unsigned long v );
247    inline void operator = ( long v );
248    inline void operator = ( unsigned int v );
249    inline void operator = ( int v );
250    inline void operator = ( sc_dt::int64 v );
251    inline void operator = ( double v );
252    inline void operator = ( const sc_int_sigref& v );
253    template<typename T>
254    inline void operator = ( const sc_dt::sc_generic_base<T>& v );
255    inline void operator = ( const sc_dt::sc_signed& v );
256    inline void operator = ( const sc_dt::sc_unsigned& v );
257    inline void operator = ( const sc_dt::sc_bv_base& v );
258    inline void operator = ( const sc_dt::sc_lv_base& v );
259
260  public:
261    static sc_vpool<sc_int_sigref> m_pool; // Pool of objects to use.
262
263  protected:
264    sc_int_part_if*                m_if_p; // Target for selection.
265
266  private:
267
268    // disabled
269    sc_int_sigref( const sc_int_sigref& a );
270};
271
272
273//==============================================================================
274// CLASS sc_signal<sc_dt::sc_int<W> >
275//
276// This class implements a signal whose value acts like an sc_dt::sc_int<W> data
277// value. This class is a specialization of the generic sc_signal class to
278// implement tailored support for the sc_dt::sc_int<W> class.
279//
280// Notes:
281//   (1) Descriptions of the methods and operators in this class appear with
282//       their implementations.
283//==============================================================================
284SC_TEMPLATE
285class sc_signal<sc_dt::sc_int<W> > :
286    public sc_signal_inout_if<sc_dt::sc_int<W> >,
287	public sc_prim_channel,
288    public sc_dt::sc_int<W>
289{
290  public: // typedefs
291    typedef sc_signal<sc_dt::sc_int<W> > this_type;
292
293  public: // constructors and destructor:
294    inline sc_signal();
295    explicit inline sc_signal(const char* name_);
296    virtual inline ~sc_signal();
297
298  public: // base methods:
299    inline bool base_event() const;
300    inline const sc_dt::sc_int<W>& base_read() const;
301    inline const sc_event& base_value_changed_event() const;
302    inline void base_write( sc_dt::int64 value );
303
304  public: // sc_prim_channel virtual methods:
305    virtual inline const char* kind() const;
306    virtual inline void update();
307
308  public: // sc_interface virtual methods:
309    virtual inline const sc_event& default_event() const;
310    virtual inline void register_port(
311		sc_port_base& port_, const char* if_typename_ );
312
313  public: // sc_int_part_if virtual methods:
314    virtual inline sc_dt::sc_int_base* part_read_target();
315    virtual inline sc_dt::uint64 read_part(int left, int right) const;
316	virtual inline sc_int_sigref& select_part(int left, int right);
317	virtual inline void write_part(sc_dt::uint64 v, int left, int right);
318
319  public: // interface virtual methods:
320    virtual inline bool event() const;
321    virtual inline const sc_dt::sc_int<W>& get_data_ref() const;
322    virtual inline sc_signal<sc_dt::sc_int<W> >& get_signal() ;
323    virtual inline const sc_dt::sc_int<W>& read() const;
324    virtual inline const sc_event& value_changed_event() const;
325    virtual inline void write( const sc_in<sc_dt::sc_int<W> >& value );
326    virtual inline void write( const sc_inout<sc_dt::sc_int<W> >& value );
327    virtual inline void write( const sc_dt::sc_int<W>& value );
328
329  public: // part selections:
330  	inline sc_int_sigref& operator () ( int left, int right );
331  	inline sc_int_sigref& operator [] ( int bit );
332
333  public: // operators:
334    inline void operator = ( const this_type& new_val );
335    inline void operator = ( const char* new_val );
336    inline void operator = ( sc_dt::uint64 new_val );
337    inline void operator = ( sc_dt::int64 new_val );
338    inline void operator = ( int new_val );
339    inline void operator = ( long new_val ) ;
340    inline void operator = ( short new_val ) ;
341    inline void operator = ( unsigned int new_val ) ;
342    inline void operator = ( unsigned long new_val );
343    inline void operator = ( unsigned short new_val );
344    template<typename T>
345    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val );
346    inline void operator = ( const sc_dt::sc_signed& new_val );
347    inline void operator = ( const sc_dt::sc_unsigned& new_val );
348    inline void operator = ( const sc_dt::sc_bv_base& new_val );
349    inline void operator = ( const sc_dt::sc_lv_base& new_val );
350
351    // concatenation methods (we inherit length and gets from sc_dt::sc_int<W>):
352
353    virtual inline void concat_set(sc_dt::int64 src, int low_i);
354    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i);
355    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i);
356    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i);
357    virtual inline void concat_set(sc_dt::uint64 src, int low_i);
358
359  protected: // debugging methods:
360    // #### void check_port();
361	void check_writer();
362
363  private: // Disabled operations that sc_dt::sc_int<W> supports:
364    sc_signal<sc_dt::sc_int<W> >& operator ++ ();          // prefix
365    const sc_signal<sc_dt::sc_int<W> >& operator ++ (int); // postfix
366    sc_signal<sc_dt::sc_int<W> >& operator -- ();          // prefix
367    const sc_signal<sc_dt::sc_int<W> >& operator -- (int); // postfix
368    sc_signal<sc_dt::sc_int<W> >& operator += (sc_dt::int_type);
369    sc_signal<sc_dt::sc_int<W> >& operator -= (sc_dt::int_type);
370    sc_signal<sc_dt::sc_int<W> >& operator *= (sc_dt::int_type);
371    sc_signal<sc_dt::sc_int<W> >& operator /= (sc_dt::int_type);
372    sc_signal<sc_dt::sc_int<W> >& operator %= (sc_dt::int_type);
373    sc_signal<sc_dt::sc_int<W> >& operator &= (sc_dt::int_type);
374    sc_signal<sc_dt::sc_int<W> >& operator |= (sc_dt::int_type);
375    sc_signal<sc_dt::sc_int<W> >& operator ^= (sc_dt::int_type);
376
377  protected:
378    mutable sc_event* m_changed_event_p; // Value changed event this object.
379    sc_dt::uint64            m_event_delta;     // Delta cycle of last event.
380    sc_dt::int64             m_new_val;         // New value for this object instance.
381    sc_port_base*     m_output_p;        // Single write port verify field.
382    sc_process_b*     m_writer_p;        // Single writer verify field.
383};
384
385
386SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
387inline bool sc_signal<sc_dt::sc_int<W> >::base_event() const
388{
389    return simcontext()->delta_count() == m_event_delta + 1;
390}
391
392
393SC_TEMPLATE // Return this object's sc_dt::sc_int<W> object instance.
394inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::base_read() const
395{
396	return *this;
397}
398
399
400SC_TEMPLATE // Return the value changed event, allocating it if necessary.
401inline const sc_event& sc_signal<sc_dt::sc_int<W> >::base_value_changed_event() const
402{
403    if ( !m_changed_event_p ) m_changed_event_p = new sc_event;
404    return *m_changed_event_p;
405}
406
407
408SC_TEMPLATE // Select a portion of a value.
409inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::select_part(int left, int right)
410{
411    sc_int_sigref* result_p = sc_int_sigref::m_pool.allocate();
412    result_p->initialize(this, left, right);
413    return *result_p;
414}
415
416
417SC_TEMPLATE // Write an sc_dt::uint64 value to this object instance.
418inline void sc_signal<sc_dt::sc_int<W> >::base_write( sc_dt::int64 value )
419{
420#   if defined(DEBUG_SYSTEMC)
421        check_writer();
422#   endif
423    m_new_val = value;
424    request_update();
425}
426
427//------------------------------------------------------------------------------
428//"sc_signal<sc_dt::sc_int<W> >::check_writer"
429//
430// This method checks to see if there is more than one writer for this
431// object instance by keeping track of the process performing the write.
432//------------------------------------------------------------------------------
433SC_TEMPLATE
434inline void sc_signal<sc_dt::sc_int<W> >::check_writer()
435{
436    sc_process_b* writer_p = sc_get_curr_process_handle();
437    if( m_writer_p == 0 )
438    {
439        m_writer_p = writer_p;
440    }
441    else if( m_writer_p != writer_p )
442    {
443        sc_signal_invalid_writer( name(), kind(),
444                                  m_writer_p->name(), writer_p->name() );
445    }
446}
447
448
449//------------------------------------------------------------------------------
450//"sc_signal<sc_dt::sc_int<W> >::concat_set"
451//
452// These virtual methods allow value assignments to this object instance
453// from various sources. The position within the supplied source of the
454// low order bit for this object instance's value is low_i.
455//     src   = source value.
456//     low_i = bit within src to serve as low order bit of this object
457//             instance's value.
458//------------------------------------------------------------------------------
459SC_TEMPLATE
460inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::int64 src, int low_i)
461{
462    if ( low_i < 64 )
463    {
464        base_write(src >> low_i);
465    }
466    else
467    {
468        base_write( src >> 63 );
469    }
470}
471
472SC_TEMPLATE
473inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_lv_base& src, int low_i)
474{
475    sc_dt::sc_unsigned tmp(src.length());
476    tmp = src >> low_i;
477    base_write( tmp.to_int64() );
478}
479
480SC_TEMPLATE
481inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_signed& src, int low_i)
482{
483    base_write( (src >> low_i).to_int64());
484}
485
486SC_TEMPLATE
487inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_unsigned& src, int low_i)
488{
489    base_write( (src >> low_i).to_int64());
490}
491
492SC_TEMPLATE
493inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::uint64 src, int low_i)
494{
495    base_write( ( low_i < 64 ) ? src >> low_i : 0 );
496}
497
498
499
500SC_TEMPLATE // Return the default event for this object instance.
501inline const sc_event& sc_signal<sc_dt::sc_int<W> >::default_event() const
502	{ return base_value_changed_event(); }
503
504
505SC_TEMPLATE // Return true if a changed event happened in the last delta cycle.
506inline bool sc_signal<sc_dt::sc_int<W> >::event() const
507	{ return base_event(); }
508
509
510SC_TEMPLATE // Return a reference to the value of this object instance.
511inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::get_data_ref() const
512	{ return *this; }
513
514
515SC_TEMPLATE // Return a pointer to this object instance.
516inline sc_signal<sc_dt::sc_int<W> >& sc_signal<sc_dt::sc_int<W> >::get_signal()
517	{ return *this; }
518
519
520SC_TEMPLATE // Return a kind value of "sc_signal".
521inline const char* sc_signal<sc_dt::sc_int<W> >::kind() const
522{
523	return "sc_signal";
524}
525
526
527//------------------------------------------------------------------------------
528//"sc_signal_uint::operator ()
529//
530// This operator returns a part selection of this object instance.
531//     left  = left-hand bit of the selection.
532//     right = right-hand bit of the selection.
533//------------------------------------------------------------------------------
534SC_TEMPLATE
535inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator () (int left, int right)
536{
537    sc_int_sigref* result_p;   // Value to return.
538
539	result_p = sc_int_sigref::m_pool.allocate();
540	result_p->initialize(this, left, right);
541	return *result_p;
542}
543
544
545//------------------------------------------------------------------------------
546//"sc_signal_uint::operator []"
547//
548// This operator returns a bit selection of this object instance.
549//     i = bit to be selected.
550//------------------------------------------------------------------------------
551SC_TEMPLATE
552inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator [] ( int bit )
553{
554    return operator () (bit,bit);
555}
556
557
558SC_TEMPLATE
559inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const this_type& new_val )
560	{ base_write( (sc_dt::int64)new_val ); }
561
562SC_TEMPLATE
563inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const char* new_val )
564	{ m_new_val = sc_dt::sc_int<64>(new_val); request_update(); }
565
566SC_TEMPLATE
567inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::uint64 new_val )
568	{ base_write((sc_dt::int64)new_val); }
569
570SC_TEMPLATE
571inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::int64 new_val )
572	{ base_write(new_val); }
573
574SC_TEMPLATE
575inline void sc_signal<sc_dt::sc_int<W> >::operator = ( int new_val )
576	{ base_write((sc_dt::int64)new_val); }
577
578SC_TEMPLATE
579inline void sc_signal<sc_dt::sc_int<W> >::operator = ( long new_val )
580	{ base_write((sc_dt::int64)new_val); }
581
582SC_TEMPLATE
583inline void sc_signal<sc_dt::sc_int<W> >::operator = ( short new_val )
584	{ base_write((sc_dt::int64)new_val); }
585
586SC_TEMPLATE
587inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned int new_val )
588	{ base_write((sc_dt::int64)new_val); }
589
590SC_TEMPLATE
591inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned long new_val )
592	{ base_write((sc_dt::int64)new_val); }
593
594SC_TEMPLATE
595inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned short new_val )
596	{ base_write((sc_dt::int64)new_val); }
597
598
599SC_TEMPLATE
600template<typename T>
601inline void sc_signal<sc_dt::sc_int<W> >::operator = (
602	const sc_dt::sc_generic_base<T>& new_val )
603	{ base_write(new_val->to_int64()); }
604
605SC_TEMPLATE
606inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_signed& new_val )
607	{ base_write(new_val.to_int64()); }
608
609SC_TEMPLATE
610inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_unsigned& new_val )
611	{ base_write(new_val.to_int64()); }
612
613SC_TEMPLATE
614inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_bv_base& new_val )
615	{ base_write( (sc_dt::sc_int<W>)new_val ); }
616
617SC_TEMPLATE
618inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_lv_base& new_val )
619	{ base_write( (sc_dt::sc_int<W>)new_val ); }
620
621
622SC_TEMPLATE
623inline sc_dt::sc_int_base* sc_signal<sc_dt::sc_int<W> >::part_read_target()
624	{ return this; }
625
626
627SC_TEMPLATE
628inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::read() const
629	{ return *this; }
630
631
632SC_TEMPLATE // Read a portion of a value.
633inline sc_dt::uint64 sc_signal<sc_dt::sc_int<W> >::read_part( int left, int right ) const
634{
635	// This pointer required for HP aCC.
636    return (this->m_val & ~sc_dt::mask_int[left][right]) >> right;
637}
638
639SC_TEMPLATE
640inline void sc_signal<sc_dt::sc_int<W> >::register_port(
641	sc_port_base& port_, const char* if_typename_ )
642{
643#       ifdef DEBUG_SYSTEMC
644		std::string nm( if_typename_ );
645		if( nm == typeid( sc_signal_inout_if<sc_dt::sc_int<W> > ).name() )
646		{
647			if( m_output_p != 0 )
648			{
649				sc_signal_invalid_writer( name(), kind(),
650					 m_output_p->name(), port_.name() );
651			}
652			m_output_p = &port_;
653		}
654#       else
655            if ( &port_ && if_typename_ ) {} // Silence unused args warning.
656#       endif
657}
658
659
660SC_TEMPLATE // Autogenerated name object instance constructor.
661inline sc_signal<sc_dt::sc_int<W> >::sc_signal() :
662	sc_prim_channel(sc_gen_unique_name( "signal" )),
663	m_changed_event_p(0),
664	m_output_p(0),
665	m_writer_p(0)
666{ }
667
668
669SC_TEMPLATE // Explicitly named object instance constructor.
670inline sc_signal<sc_dt::sc_int<W> >::sc_signal(const char* name_) :
671	sc_prim_channel(name_),
672	m_changed_event_p(0),
673	m_output_p(0),
674	m_writer_p(0)
675{ }
676
677
678SC_TEMPLATE // Object instance destructor.
679inline sc_signal<sc_dt::sc_int<W> >::~sc_signal()
680{
681	if ( m_changed_event_p ) delete m_changed_event_p;
682}
683
684
685SC_TEMPLATE // Update the current value from new value.
686inline void sc_signal<sc_dt::sc_int<W> >::update()
687{
688    if ( m_changed_event_p )
689    {
690		// This pointer required for HP aCC.
691        sc_dt::int64 old_val = this->m_val;
692        sc_dt::sc_int_base::operator = (m_new_val);
693        if ( old_val != this->m_val )
694        {
695            m_changed_event_p->notify_delayed();
696            m_event_delta = simcontext()->delta_count();
697        }
698    }
699    else
700    {
701        sc_dt::sc_int_base::operator = (m_new_val);
702    }
703}
704
705
706SC_TEMPLATE // Return the value changed event.
707inline const sc_event& sc_signal<sc_dt::sc_int<W> >::value_changed_event() const
708	{ return base_value_changed_event(); }
709
710
711SC_TEMPLATE // Write a sc_in<sc_dt::sc_int<W> > value to this object instance.
712inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_in<sc_dt::sc_int<W> >& value )
713	{ base_write( value.operator sc_dt::int64 () ); }
714
715
716SC_TEMPLATE // Write a sc_inout<sc_dt::sc_int<W> > value to this object instance.
717inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_inout<sc_dt::sc_int<W> >& value )
718	{ base_write( value.operator sc_dt::int64 () ); }
719
720
721SC_TEMPLATE // Write a sc_dt::sc_int<W> value to this object instance.
722inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_dt::sc_int<W>& value )
723	{ base_write( value); }
724
725
726SC_TEMPLATE // Write a portion of a value. If this is the first write in
727            // a delta cycle we copy the existing value before setting the bits.
728inline void sc_signal<sc_dt::sc_int<W> >::write_part( sc_dt::uint64 v, int left, int right )
729{
730    sc_dt::int64  new_v;   // New value.
731    sc_dt::uint64 keep;    // Keep mask value.
732
733    keep = sc_dt::mask_int[left][right];
734    new_v = (m_new_val & keep) | ((v << right) & ~keep);
735	if ( m_new_val != new_v ) request_update();
736    m_new_val = new_v;
737}
738
739
740//==============================================================================
741// CLASS sc_in<sc_dt::sc_int<W> >
742//
743// This class implements an input port whose target acts like an sc_dt::sc_int<W> data
744// value. This class is a specialization of the generic sc_in class to
745// implement tailored support for the sc_dt::sc_int<W> class.
746//==============================================================================
747SC_TEMPLATE
748class sc_in<sc_dt::sc_int<W> > :
749    public sc_port<sc_signal_in_if<sc_dt::sc_int<W> >, 1>,
750    public sc_dt::sc_value_base
751{
752  public:
753
754    // typedefs
755
756    typedef sc_dt::sc_int<W>                      data_type;
757    typedef sc_signal_in_if<sc_dt::sc_int<W> >    if_type;
758    typedef sc_port<if_type,1>                    base_type;
759    typedef sc_in<sc_dt::sc_int<W> >              this_type;
760
761    typedef if_type                               in_if_type;
762    typedef base_type                             in_port_type;
763    typedef sc_signal_inout_if<sc_dt::sc_int<W> > inout_if_type;
764    typedef sc_inout<sc_dt::sc_int<W> >           inout_port_type;
765
766  public:
767
768    // bind methods and operators:
769
770    void bind( const in_if_type& interface_ )
771        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
772    void operator () ( const in_if_type& interface_ )
773        { sc_port_base::bind( const_cast<in_if_type&>( interface_) );}
774    void bind( in_port_type& parent_ )
775        { sc_port_base::bind(parent_);}
776    void operator () ( in_port_type& parent_ )
777        { sc_port_base::bind(parent_);}
778    void bind( inout_port_type& parent_ )
779        { sc_port_base::bind(parent_);}
780    void operator () ( inout_port_type& parent_ )
781        { sc_port_base::bind(parent_);}
782
783  protected:
784    // called by pbind (for internal use only)
785    virtual inline int vbind( sc_interface& interface_ )
786        {
787            return sc_port_b<if_type>::vbind( interface_ );
788        }
789    virtual inline int vbind( sc_port_base& parent_ )
790        {
791            in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ );
792            if( in_parent != 0 ) {
793                sc_port_base::bind( *in_parent );
794                return 0;
795            }
796            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
797            if( inout_parent != 0 ) {
798                sc_port_base::bind( *inout_parent );
799                return 0;
800            }
801            // type mismatch
802            return 2;
803        }
804
805
806    // constructors
807
808  public:
809    sc_in()
810        : base_type(), m_traces( 0 )
811        {}
812
813    explicit sc_in( const char* name_ )
814        : base_type( name_ ), m_traces( 0 )
815        {}
816
817    explicit sc_in( const in_if_type& interface_ )
818        : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
819        {}
820
821    sc_in( const char* name_, const in_if_type& interface_ )
822        : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 )
823        {}
824
825    explicit sc_in( in_port_type& parent_ )
826        : base_type( parent_ ), m_traces( 0 )
827        {}
828
829    sc_in( const char* name_, in_port_type& parent_ )
830        : base_type( name_, parent_ ), m_traces( 0 )
831        {}
832
833    explicit sc_in( inout_port_type& parent_ )
834        : base_type(), m_traces( 0 )
835        { sc_port_base::bind( parent_ ); }
836
837    sc_in( const char* name_, inout_port_type& parent_ )
838        : base_type( name_ ), m_traces( 0 )
839        { sc_port_base::bind( parent_ ); }
840
841    sc_in( this_type& parent_ )
842        : base_type( parent_ ), m_traces( 0 )
843        {}
844
845    sc_in( const char* name_, this_type& parent_ )
846        : base_type( name_, parent_ ), m_traces( 0 )
847        {}
848
849
850    // destructor
851
852    virtual inline ~sc_in()
853        {
854            remove_traces();
855        }
856
857    // bit and part selection
858
859    sc_dt::sc_int_bitref_r operator [] ( int i ) const
860        { return (*this)->read()[i]; }
861    sc_dt::sc_int_bitref_r bit( int i ) const
862        { return (*this)->read()[i]; }
863    sc_dt::sc_int_subref_r operator () ( int left, int right ) const
864        { return (*this)->read()(left,right); }
865    sc_dt::sc_int_subref_r range( int left, int right ) const
866        { return (*this)->read()(left,right); }
867
868
869    // interface access shortcut methods
870
871    // get the default event
872
873    const sc_event& default_event() const
874        { return (*this)->value_changed_event(); }
875
876
877    // get the value changed event
878
879    const sc_event& value_changed_event() const
880        { return (*this)->value_changed_event(); }
881
882
883    // read the current value
884
885    const sc_dt::sc_int<W>& read() const
886        { return (*this)->read(); }
887
888	operator sc_dt::int64 () const
889		{ return (sc_dt::int64)(*this)->read(); }
890
891    // was there a value changed event?
892
893    bool event() const
894        { return (*this)->event(); }
895
896
897    // (other) event finder method(s)
898
899    sc_event_finder& value_changed() const
900        {
901            return *new sc_event_finder_t<in_if_type>(
902                *this, &in_if_type::value_changed_event );
903        }
904
905
906
907    // reduction methods:
908
909    inline bool and_reduce() const
910        { return (*this)->read().and_reduce(); }
911    inline bool nand_reduce() const
912        { return (*this)->read().nand_reduce(); }
913    inline bool nor_reduce() const
914        { return (*this)->read().nor_reduce(); }
915    inline bool or_reduce() const
916        { return (*this)->read().or_reduce(); }
917    inline bool xnor_reduce() const
918        { return (*this)->read().xnor_reduce(); }
919    inline bool xor_reduce() const
920        { return (*this)->read().xor_reduce(); }
921
922
923    // called when elaboration is done
924    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
925    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
926
927    virtual inline void end_of_elaboration()
928        {
929            if( m_traces != 0 ) {
930                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
931                    sc_trace_params* p = (*m_traces)[i];
932                    sc_trace( p->tf, read(), p->name );
933                }
934                remove_traces();
935            }
936        }
937
938    virtual inline const char* kind() const
939        { return "sc_in"; }
940
941
942    // called by sc_trace
943    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
944        {
945            if( tf_ != 0 ) {
946                if( m_traces == 0 ) {
947                    m_traces = new sc_trace_params_vec;
948                }
949                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
950            }
951        }
952
953
954    // concatenation methods
955
956    virtual inline int concat_length(bool* xz_present_p) const
957        { return (*this)->read().concat_length( xz_present_p ); }
958    virtual inline sc_dt::uint64 concat_get_uint64() const
959        { return (*this)->read().concat_get_uint64(); }
960    virtual
961	inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
962        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
963    virtual
964	inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
965        { return (*this)->read().concat_get_data(dst_p, low_i); }
966
967  protected:
968    void remove_traces() const
969        {
970            if( m_traces != 0 ) {
971                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
972                    delete (*m_traces)[i];
973                }
974                delete m_traces;
975                m_traces = 0;
976            }
977        }
978
979    mutable sc_trace_params_vec* m_traces;
980
981
982  private:
983
984    // disabled
985    sc_in( const sc_in<sc_dt::sc_int<W> >& );
986    sc_in<sc_dt::sc_int<W> >& operator = ( const sc_in<sc_dt::sc_int<W> >& );
987
988#ifdef __GNUC__
989    // Needed to circumvent a problem in the g++-2.95.2 compiler:
990    // This unused variable forces the compiler to instantiate
991    // an object of T template so an implicit conversion from
992    // read() to a C++ intrinsic data type will work.
993    static data_type dummy;
994#endif
995
996};
997
998
999
1000SC_TEMPLATE
1001inline std::ostream& operator << (std::ostream& os, const sc_in<sc_dt::sc_int<W> >& a)
1002{
1003    a.read().print( os );
1004    return os;
1005}
1006
1007
1008//==============================================================================
1009// CLASS sc_inout<sc_dt::sc_int<W> >
1010//
1011// This class implements an input/output port whose target acts like an
1012// sc_dt::sc_int<W> data value. It is derived from the sc_int_in. This class is a
1013// specialization of the generic sc_inout class to implement tailored support
1014// for the sc_dt::sc_int<W> class.
1015//==============================================================================
1016SC_TEMPLATE
1017class sc_inout<sc_dt::sc_int<W> > :
1018    public sc_port<sc_signal_inout_if<sc_dt::sc_int<W> >, 1>,
1019    public sc_dt::sc_value_base
1020{
1021  public:
1022
1023    // typedefs
1024
1025    typedef sc_dt::sc_int<W>                    data_type;
1026    typedef sc_signal_inout_if<sc_dt::sc_int<W> > if_type;
1027    typedef sc_port<if_type,1>              base_type;
1028    typedef sc_inout<sc_dt::sc_int<W> >           this_type;
1029
1030    typedef if_type                         inout_if_type;
1031    typedef base_type                       inout_port_type;
1032
1033  public:
1034
1035    // bind methods and operators:
1036
1037    void bind( const inout_if_type& interface_ )
1038        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
1039    void operator () ( const inout_if_type& interface_ )
1040        { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); }
1041    void bind( inout_port_type& parent_ )
1042        { sc_port_base::bind(parent_); }
1043    void operator () ( inout_port_type& parent_ )
1044        { sc_port_base::bind(parent_); }
1045
1046  protected:
1047    // called by pbind (for internal use only)
1048    virtual inline int vbind( sc_interface& interface_ )
1049        {
1050            return sc_port_b<if_type>::vbind( interface_ );
1051        }
1052    virtual inline int vbind( sc_port_base& parent_ )
1053        {
1054            inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ );
1055            if( inout_parent != 0 ) {
1056                sc_port_base::bind( *inout_parent );
1057                return 0;
1058            }
1059            // type mismatch
1060            return 2;
1061        }
1062
1063
1064    // constructors
1065
1066  public:
1067    sc_inout()
1068        : base_type(), m_init_val_p(0), m_traces( 0 )
1069        {}
1070
1071    explicit sc_inout( const char* name_ )
1072        : base_type( name_ ), m_init_val_p(0), m_traces( 0 )
1073        {}
1074
1075    explicit sc_inout( inout_if_type& interface_ )
1076        : base_type( interface_ ), m_init_val_p(0), m_traces( 0 )
1077        {}
1078
1079    sc_inout( const char* name_, inout_if_type& interface_ )
1080        : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 )
1081        {}
1082
1083    explicit sc_inout( inout_port_type& parent_ )
1084        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
1085        {}
1086
1087    sc_inout( const char* name_, inout_port_type& parent_ )
1088        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
1089        {}
1090
1091    sc_inout( this_type& parent_ )
1092        : base_type( parent_ ), m_init_val_p(0), m_traces( 0 )
1093        {}
1094
1095    sc_inout( const char* name_, this_type& parent_ )
1096        : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 )
1097        {}
1098
1099
1100    // destructor
1101
1102    virtual inline ~sc_inout()
1103        {
1104            remove_traces();
1105        }
1106
1107    // bit and part selection
1108
1109    sc_dt::sc_int_bitref_r operator [] ( int i ) const
1110        { return (*this)->read()[i]; }
1111    sc_dt::sc_int_bitref_r bit( int i ) const
1112        { return (*this)->read()[i]; }
1113    sc_int_sigref& operator [] ( int i )
1114		{ return (*this)->select_part(i,i); }
1115    sc_int_sigref& bit( int i )
1116		{ return (*this)->select_part(i,i); }
1117    sc_dt::sc_int_subref_r operator () ( int left, int right ) const
1118        { return (*this)->read()(left,right); }
1119    sc_dt::sc_int_subref_r range( int left, int right ) const
1120        { return (*this)->read()(left,right); }
1121    sc_int_sigref& operator () ( int left, int right )
1122		{ return (*this)->select_part(left,right); }
1123    sc_int_sigref& range( int left, int right )
1124		{ return (*this)->select_part(left,right); }
1125
1126
1127    // interface access shortcut methods
1128
1129    // get the default event
1130
1131    const sc_event& default_event() const
1132        { return (*this)->value_changed_event(); }
1133
1134
1135    // get the value changed event
1136
1137    const sc_event& value_changed_event() const
1138        { return (*this)->value_changed_event(); }
1139
1140
1141    // read the current value
1142
1143    const sc_dt::sc_int<W>& read() const
1144        { return (*this)->read(); }
1145
1146	operator sc_dt::int64 () const
1147		{ return (sc_dt::int64)(*this)->read(); }
1148
1149    // was there a value changed event?
1150
1151    bool event() const
1152        { return (*this)->event(); }
1153
1154
1155    // (other) event finder method(s)
1156
1157    sc_event_finder& value_changed() const
1158        {
1159            return *new sc_event_finder_t<inout_if_type>(
1160                *this, &inout_if_type::value_changed_event );
1161        }
1162
1163
1164
1165    // reduction methods:
1166
1167    inline bool and_reduce() const
1168        { return (*this)->read().and_reduce(); }
1169    inline bool nand_reduce() const
1170        { return (*this)->read().nand_reduce(); }
1171    inline bool nor_reduce() const
1172        { return (*this)->read().nor_reduce(); }
1173    inline bool or_reduce() const
1174        { return (*this)->read().or_reduce(); }
1175    inline bool xnor_reduce() const
1176        { return (*this)->read().xnor_reduce(); }
1177    inline bool xor_reduce() const
1178        { return (*this)->read().xor_reduce(); }
1179
1180
1181    // called when elaboration is done
1182    /*  WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
1183    /*  MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
1184
1185    virtual inline void end_of_elaboration()
1186        {
1187            if( m_init_val_p != 0 ) {
1188                (*this)->write( (sc_dt::int64) *m_init_val_p );
1189                delete m_init_val_p;
1190                m_init_val_p = 0;
1191            }
1192            if( m_traces != 0 ) {
1193                for( unsigned int i = 0; i < m_traces->size(); ++ i ) {
1194                    sc_trace_params* p = (*m_traces)[i];
1195                    sc_trace( p->tf, read(), p->name );
1196                }
1197                remove_traces();
1198            }
1199        }
1200
1201    virtual inline const char* kind() const
1202        { return "sc_inout"; }
1203
1204    // value initialization
1205
1206    inline void initialize( const sc_dt::sc_int<W>& value_ )
1207    {
1208        inout_if_type* iface = this->get_interface(0);
1209        if( iface != 0 ) {
1210            iface->write( value_ );
1211        } else {
1212            if( m_init_val_p == 0 ) {
1213                m_init_val_p = new sc_dt::int64;
1214            }
1215            *m_init_val_p = value_;
1216        }
1217    }
1218
1219
1220    // called by sc_trace
1221    void add_trace( sc_trace_file* tf_, const std::string& name_ ) const
1222        {
1223            if( tf_ != 0 ) {
1224                if( m_traces == 0 ) {
1225                    m_traces = new sc_trace_params_vec;
1226                }
1227                m_traces->push_back( new sc_trace_params( tf_, name_ ) );
1228            }
1229        }
1230
1231
1232    // concatenation methods
1233
1234    virtual inline int concat_length(bool* xz_present_p) const
1235        { return (*this)->read().concat_length( xz_present_p ); }
1236    virtual inline sc_dt::uint64 concat_get_uint64() const
1237        { return (*this)->read().concat_get_uint64(); }
1238    virtual
1239	inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const
1240        { return (*this)->read().concat_get_ctrl(dst_p, low_i); }
1241    virtual
1242	inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const
1243        { return (*this)->read().concat_get_data(dst_p, low_i); }
1244    virtual inline void concat_set(sc_dt::int64 src, int low_i)
1245        { *this = src >> (( low_i < 64 ) ? low_i : 63); }
1246#if 0 // ####
1247    virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i)
1248        { *this = src >> low_i; }
1249#endif // 0 ####
1250    virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i)
1251        { *this = src >> low_i; }
1252    virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i)
1253        { *this = src >> low_i; }
1254    virtual inline void concat_set(sc_dt::uint64 src, int low_i)
1255        { *this = ( low_i < 64 ) ? src >> low_i : (sc_dt::uint64)0; }
1256
1257    // assignment operators:
1258
1259  public:
1260	inline void operator = ( const this_type& new_val )
1261		{ (*this)->write( (sc_dt::int64)new_val ); }
1262    inline void operator = ( const char* new_val )
1263        { (*this)->write( this_type(new_val) ); }
1264    inline void operator = ( sc_dt::uint64 new_val )
1265        { (*this)->write(new_val); }
1266    inline void operator = ( sc_dt::int64 new_val )
1267        { (*this)->write((sc_dt::uint64)new_val); }
1268    inline void operator = ( int new_val )
1269        { (*this)->write((sc_dt::uint64)new_val); }
1270    inline void operator = ( long new_val )
1271        { (*this)->write((sc_dt::uint64)new_val); }
1272    inline void operator = ( short new_val )
1273        { (*this)->write((sc_dt::uint64)new_val); }
1274    inline void operator = ( unsigned int new_val )
1275        { (*this)->write((sc_dt::uint64)new_val); }
1276    inline void operator = ( unsigned long new_val )
1277        { (*this)->write((sc_dt::uint64)new_val); }
1278    inline void operator = ( unsigned short new_val )
1279        { (*this)->write((sc_dt::uint64)new_val); }
1280    template<typename T>
1281    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
1282        { (*this)->write(new_val->to_uint64()); }
1283    inline void operator = ( const sc_dt::sc_signed& new_val )
1284        { (*this)->write(new_val.to_uint64()); }
1285    inline void operator = ( const sc_dt::sc_unsigned& new_val )
1286        { (*this)->write(new_val.to_uint64()); }
1287    inline void operator = ( const sc_dt::sc_bv_base& new_val )
1288        { (*this)->write((sc_dt::sc_int<W>)new_val); }
1289    inline void operator = ( const sc_dt::sc_lv_base& new_val )
1290        { (*this)->write((sc_dt::sc_int<W>)new_val); }
1291
1292    inline void write( const sc_in<sc_dt::sc_int<W> >& new_val )
1293        { (*this)->write( (sc_dt::int64)new_val ); }
1294
1295    inline void write( const sc_inout<sc_dt::sc_int<W> >& new_val )
1296        { (*this)->write( (sc_dt::int64)new_val); }
1297
1298    inline void write( const sc_dt::sc_int<W>& new_val )
1299        { (*this)->write( (sc_dt::int64)new_val); }
1300
1301  protected:
1302    void remove_traces() const
1303        {
1304            if( m_traces != 0 ) {
1305                for( int i = m_traces->size() - 1; i >= 0; -- i ) {
1306                    delete (*m_traces)[i];
1307                }
1308                delete m_traces;
1309                m_traces = 0;
1310            }
1311        }
1312
1313    sc_dt::int64*                      m_init_val_p;
1314    mutable sc_trace_params_vec* m_traces;
1315
1316
1317  private:
1318
1319    // disabled
1320    sc_inout( const sc_inout<sc_dt::sc_int<W> >& );
1321
1322#ifdef __GNUC__
1323    // Needed to circumvent a problem in the g++-2.95.2 compiler:
1324    // This unused variable forces the compiler to instantiate
1325    // an object of T template so an implicit conversion from
1326    // read() to a C++ intrinsic data type will work.
1327    static data_type dummy;
1328#endif
1329
1330};
1331
1332
1333
1334SC_TEMPLATE
1335inline std::ostream& operator << (
1336	std::ostream& os, const sc_inout<sc_dt::sc_int<W> >& a )
1337{
1338    a.read().print( os );
1339    return os;
1340}
1341
1342
1343//==============================================================================
1344// CLASS sc_out<sc_dt::sc_int<W> >
1345//
1346// This class implements an output port whose target acts like an
1347// sc_dt::sc_int<W> data value. This class is a derivation of sc_inout, since
1348// output ports are really no different from input/output ports.
1349//==============================================================================
1350SC_TEMPLATE
1351class sc_out<sc_dt::sc_int<W> > : public sc_inout<sc_dt::sc_int<W> >
1352{
1353  public:
1354
1355    // typedefs
1356
1357    typedef sc_dt::sc_int<W>                          data_type;
1358
1359    typedef sc_out<data_type>                   this_type;
1360    typedef sc_inout<data_type>                 base_type;
1361
1362    typedef typename base_type::inout_if_type   inout_if_type;
1363    typedef typename base_type::inout_port_type inout_port_type;
1364
1365    // constructors
1366
1367    sc_out()
1368        : base_type()
1369        {}
1370
1371    explicit sc_out( const char* name_ )
1372        : base_type( name_ )
1373        {}
1374
1375    explicit sc_out( inout_if_type& interface_ )
1376        : base_type( interface_ )
1377        {}
1378
1379    sc_out( const char* name_, inout_if_type& interface_ )
1380        : base_type( name_, interface_ )
1381        {}
1382
1383    explicit sc_out( inout_port_type& parent_ )
1384        : base_type( parent_ )
1385        {}
1386
1387    sc_out( const char* name_, inout_port_type& parent_ )
1388        : base_type( name_, parent_ )
1389        {}
1390
1391    sc_out( this_type& parent_ )
1392        : base_type( parent_ )
1393        {}
1394
1395    sc_out( const char* name_, this_type& parent_ )
1396        : base_type( name_, parent_ )
1397        {}
1398
1399
1400    // destructor (does nothing)
1401
1402    virtual inline ~sc_out()
1403        {}
1404
1405
1406    // assignment operators:
1407
1408  public:
1409	inline void operator = ( const this_type& new_val )
1410		{ (*this)->write( (sc_dt::int64)new_val ); }
1411    inline void operator = ( const char* new_val )
1412		{ (*this)->write( this_type(new_val) ); }
1413    inline void operator = ( sc_dt::uint64 new_val )
1414        { (*this)->write(new_val); }
1415    inline void operator = ( sc_dt::int64 new_val )
1416        { (*this)->write((sc_dt::uint64)new_val); }
1417    inline void operator = ( int new_val )
1418        { (*this)->write((sc_dt::uint64)new_val); }
1419    inline void operator = ( long new_val )
1420        { (*this)->write((sc_dt::uint64)new_val); }
1421    inline void operator = ( short new_val )
1422        { (*this)->write((sc_dt::uint64)new_val); }
1423    inline void operator = ( unsigned int new_val )
1424        { (*this)->write((sc_dt::uint64)new_val); }
1425    inline void operator = ( unsigned long new_val )
1426        { (*this)->write((sc_dt::uint64)new_val); }
1427    inline void operator = ( unsigned short new_val )
1428        { (*this)->write((sc_dt::uint64)new_val); }
1429    template<typename T>
1430    inline void operator = ( const sc_dt::sc_generic_base<T>& new_val )
1431        { (*this)->write(new_val->to_uint64()); }
1432    inline void operator = ( const sc_dt::sc_signed& new_val )
1433        { (*this)->write(new_val); }
1434    inline void operator = ( const sc_dt::sc_unsigned& new_val )
1435        { (*this)->write(new_val); }
1436    inline void operator = ( const sc_dt::sc_bv_base& new_val )
1437        { (*this)->write((sc_dt::sc_int<W>)new_val); }
1438    inline void operator = ( const sc_dt::sc_lv_base& new_val )
1439        { (*this)->write((sc_dt::sc_int<W>)new_val); }
1440
1441  private:
1442
1443    // disabled
1444    sc_out( const this_type& );
1445};
1446
1447
1448
1449//------------------------------------------------------------------------------
1450//"sc_int_sigref::initialize"
1451//
1452// This method initializes an object instance from the supplied arguments.
1453//     if_p  -> access to target of this selection.
1454//     left  =  left-most bit in selection.
1455//     right =  right-most bit in selection.
1456//------------------------------------------------------------------------------
1457inline
1458void sc_int_sigref::initialize(sc_int_part_if* if_p, int left, int right)
1459{
1460    m_if_p = if_p;
1461    m_left = left;
1462    m_right = right;
1463	m_obj_p = if_p->part_read_target();
1464}
1465
1466
1467//------------------------------------------------------------------------------
1468//"sc_int_sigref::operator ="
1469//
1470// These operators assign a value to the bits associated with this object
1471// instance within this object instance's target signal.
1472//------------------------------------------------------------------------------
1473inline void sc_int_sigref::operator = ( sc_dt::uint64 v )
1474{
1475	m_if_p->write_part( v, m_left, m_right );
1476}
1477
1478inline void sc_int_sigref::operator = ( const char* /*v*/ )
1479{
1480}
1481
1482inline void sc_int_sigref:: operator = ( sc_dt::int64 v )
1483{
1484    *this = (sc_dt::uint64)v;
1485}
1486
1487inline void sc_int_sigref:: operator = ( int v )
1488{
1489    *this = (sc_dt::uint64)v;
1490}
1491
1492inline void sc_int_sigref:: operator = ( long v )
1493{
1494    *this = (sc_dt::uint64)v;
1495}
1496
1497inline void sc_int_sigref:: operator = ( unsigned int v )
1498{
1499    *this = (sc_dt::uint64)v;
1500}
1501
1502inline void sc_int_sigref:: operator = ( unsigned long v )
1503{
1504    *this = (sc_dt::uint64)v;
1505}
1506
1507void sc_int_sigref::operator = ( const sc_int_sigref& v )
1508{
1509    *this = (sc_dt::uint64)v;
1510}
1511
1512template<typename T>
1513inline void sc_int_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v )
1514{
1515    *this = v->to_uint64();
1516}
1517
1518inline void sc_int_sigref:: operator = ( const sc_dt::sc_signed& v )
1519{
1520    *this = v.to_uint64();
1521}
1522
1523inline void sc_int_sigref:: operator = ( const sc_dt::sc_unsigned& v )
1524{
1525    *this = v.to_uint64();
1526}
1527
1528#undef SC_TEMPLATE
1529#undef TTEST
1530} // namespace sc_core
1531#endif // !defined(SC_SIGNAL_INT_H)
1532
1533namespace sc_core {
1534
1535extern
1536void
1537sc_signal_invalid_writer( const char* name,
1538                          const char* kind,
1539                          const char* first_writer,
1540                          const char* second_writer );
1541
1542//------------------------------------------------------------------------------
1543// POOL OF TEMPORARY INSTANCES OF sc_int_sigref
1544//
1545// This allows use to pass const references for part and bit selections
1546// on sc_signal_int object instances.
1547//------------------------------------------------------------------------------
1548sc_vpool<sc_int_sigref> sc_int_sigref::m_pool(8);
1549
1550
1551//------------------------------------------------------------------------------
1552//"sc_int_part_if::default methods"
1553//
1554// These versions just produce errors if they are not overloaded but used.
1555//------------------------------------------------------------------------------
1556
1557sc_dt::sc_int_base* sc_int_part_if::part_read_target()
1558{
1559    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1560    return 0;
1561}
1562sc_dt::uint64 sc_int_part_if::read_part( int /*left*/, int /*right*/ ) const
1563{
1564    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1565    return 0;
1566}
1567sc_int_sigref& sc_int_part_if::select_part( int /*left*/, int /*right*/ )
1568{
1569    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1570    return *(sc_int_sigref*)0;
1571}
1572void sc_int_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ )
1573{
1574    SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1575}
1576
1577
1578//------------------------------------------------------------------------------
1579//"sc_int_sigref::concate_set"
1580//
1581// These methods assign this object instance's value from the supplied
1582// value starting at the supplied bit within that value.
1583//     src = value to use to set this object instance's value.
1584//     low_i = bit in src that is to be the low order bit of the value to set.
1585// #### OPTIMIZE
1586//------------------------------------------------------------------------------
1587void sc_int_sigref::concat_set(sc_dt::int64 src, int low_i)
1588{
1589    *this = (low_i < 64) ? src >> low_i : src >> 63;
1590}
1591
1592
1593void sc_int_sigref::concat_set(const sc_dt::sc_signed& src, int low_i)
1594{
1595    if ( low_i < src.length() )
1596        *this = src >> low_i;
1597    else
1598        *this = (src < 0) ? (sc_dt::uint64)-1 : 0;
1599}
1600
1601
1602void sc_int_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i)
1603{
1604    if ( low_i < src.length() )
1605        *this = (src >> low_i).to_uint64();
1606    else
1607        *this = 0;
1608}
1609
1610
1611void sc_int_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i)
1612{
1613    if ( low_i < src.length() )
1614        *this = src >> low_i;
1615    else
1616        *this = 0;
1617}
1618
1619
1620void sc_int_sigref::concat_set(sc_dt::uint64 src, int low_i)
1621{
1622    *this = (low_i < 64) ? src >> low_i : 0;
1623}
1624
1625} // namespace sc_core
1626