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