scx_signal_uint.h (12922:a4f51f3405ac) scx_signal_uint.h (13324:c8b709468e61)
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{
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" );
1607 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1609 return 0;
1610}
1611sc_dt::uint64 sc_uint_part_if::read_part( int /*left*/, int /*right*/ ) const
1612{
1608 return 0;
1609}
1610sc_dt::uint64 sc_uint_part_if::read_part( int /*left*/, int /*right*/ ) const
1611{
1613 SC_REPORT_ERROR( "attempted specalized signal operation on "
1614 "non-specialized signal", "int" );
1612 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" );
1615 return 0;
1616}
1617sc_uint_sigref& sc_uint_part_if::select_part( int /*left*/, int /*right*/ )
1618{
1613 return 0;
1614}
1615sc_uint_sigref& sc_uint_part_if::select_part( int /*left*/, int /*right*/ )
1616{
1619 SC_REPORT_ERROR( "attempted specalized signal operation on "
1620 "non-specialized signal", "int" );
1617 SC_REPORT_ERROR( SC_ID_OPERATION_ON_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{
1618 return *(sc_uint_sigref*)0;
1619}
1620void sc_uint_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ )
1621{
1625 SC_REPORT_ERROR( "attempted specalized signal operation on "
1626 "non-specialized signal", "int" );
1622 SC_REPORT_ERROR( SC_ID_OPERATION_ON_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
1623}
1624
1625//------------------------------------------------------------------------------
1626//"sc_uint_sigref::concate_set"
1627//
1628// These methods assign this object instance's value from the supplied
1629// value starting at the supplied bit within that value.
1630// src = value to use to set this object instance's value.
1631// low_i = bit in src that is to be the low order bit of the value to set.
1632// #### OPTIMIZE
1633//------------------------------------------------------------------------------
1634void sc_uint_sigref::concat_set(sc_dt::int64 src, int low_i)
1635{
1636 *this = (low_i < 64) ? src >> low_i : src >> 63;
1637}
1638
1639
1640void sc_uint_sigref::concat_set(const sc_dt::sc_signed& src, int low_i)
1641{
1642 if ( low_i < src.length() )
1643 *this = src >> low_i;
1644 else
1645 *this = (src < 0) ? (sc_dt::uint64)-1 : 0;
1646}
1647
1648
1649void sc_uint_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i)
1650{
1651 if ( low_i < src.length() )
1652 *this = (src >> low_i).to_uint64();
1653 else
1654 *this = 0;
1655}
1656
1657
1658void sc_uint_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i)
1659{
1660 if ( low_i < src.length() )
1661 *this = src >> low_i;
1662 else
1663 *this = 0;
1664}
1665
1666
1667void sc_uint_sigref::concat_set(sc_dt::uint64 src, int low_i)
1668{
1669 *this = (low_i < 64) ? src >> low_i : 0;
1670}
1671
1672} // namespace sc_core