sc_int_base.hh (12853:e23d6f09069a) sc_int_base.hh (13159:b5728438028b)
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_int_base.h -- A signed integer whose length is less than 64 bit.
23
24 Unlike arbitrary precision, arithmetic and bitwise operations
25 are performed using the native types (hence capped at 64 bits).
26 The sc_int integer is useful when the user does not need
27 arbitrary precision and the performance is superior to
28 sc_bigint/sc_biguint.
29
30 Original Author: Amit Rao, Synopsys, Inc.
31
32 *****************************************************************************/
33
34/*****************************************************************************
35
36 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
37 changes you are making here.
38
39 Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
40 Description of Modification: - Resolved ambiguity with sc_(un)signed.
41 - Merged the code for 64- and 32-bit versions
42 via the constants in sc_nbdefs.h.
43 - Eliminated redundant file inclusions.
44
45 Name, Affiliation, Date:
46 Description of Modification:
47
48 *****************************************************************************/
49
50// $Log: sc_int_base.h,v $
51// Revision 1.3 2011/08/24 22:05:45 acg
52// Torsten Maehne: initialization changes to remove warnings.
53//
54// Revision 1.2 2011/02/18 20:19:15 acg
55// Andy Goodrich: updating Copyright notice.
56//
57// Revision 1.1.1.1 2006/12/15 20:20:05 acg
58// SystemC 2.3
59//
60// Revision 1.4 2006/05/08 17:50:01 acg
61// Andy Goodrich: Added David Long's declarations for friend operators,
62// functions, and methods, to keep the Microsoft compiler happy.
63//
64// Revision 1.3 2006/01/13 18:49:31 acg
65// Added $Log command so that CVS check in comments are reproduced in the
66// source.
67//
68
69#ifndef __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
70#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
71
72#include <iostream>
73
74#include "../misc/sc_value_base.hh"
75#include "../sc_temporary.hh"
76#include "sc_length_param.hh"
77#include "sc_nbdefs.hh"
78#include "sc_uint_base.hh"
79
80namespace sc_dt
81{
82
83class sc_concatref;
84
85// classes defined in this module
86class sc_int_bitref_r;
87class sc_int_bitref;
88class sc_int_subref_r;
89class sc_int_subref;
90class sc_int_base;
91class sc_signed_subref_r;
92class sc_unsigned_subref_r;
93
94// forward class declarations
95class sc_bv_base;
96class sc_lv_base;
97class sc_signed;
98class sc_unsigned;
99class sc_fxval;
100class sc_fxval_fast;
101class sc_fxnum;
102class sc_fxnum_fast;
103
104} // namespace sc_dt
105
106// extern template instantiations
107namespace sc_core
108{
109
110extern template class sc_vpool<sc_dt::sc_int_bitref>;
111extern template class sc_vpool<sc_dt::sc_int_subref>;
112
113} // namespace sc_core
114
115namespace sc_dt
116{
117
118extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
119
120// friend operator declarations
121
122// relational operators
123
124inline bool operator == (const sc_int_base &a, const sc_int_base &b);
125inline bool operator != (const sc_int_base &a, const sc_int_base &b);
126inline bool operator < (const sc_int_base &a, const sc_int_base &b);
127inline bool operator <= (const sc_int_base &a, const sc_int_base &b);
128inline bool operator > (const sc_int_base &a, const sc_int_base &b);
129inline bool operator >= (const sc_int_base &a, const sc_int_base &b);
130
131
132// ----------------------------------------------------------------------------
133// CLASS : sc_int_bitref_r
134//
135// Proxy class for sc_int bit selection (r-value only).
136// ----------------------------------------------------------------------------
137
138class sc_int_bitref_r : public sc_value_base
139{
140 friend class sc_int_base;
141
142 protected:
143 // constructor
144 sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {}
145
146 // initializer for sc_core::sc_vpool:
147 void initialize(const sc_int_base *obj_p, int index_)
148 {
149 m_obj_p = (sc_int_base *)obj_p;
150 m_index = index_;
151 }
152
153 public:
154 // copy constructor
155 sc_int_bitref_r(const sc_int_bitref_r &a) :
156 sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
157 {}
158
159 // destructor
160 virtual ~sc_int_bitref_r() {}
161
162 // capacity
163 int length() const { return 1; }
164
165#ifdef SC_DT_DEPRECATED
166 int bitwidth() const { return length(); }
167#endif
168
169 // concatenation support
170 virtual int
171 concat_length(bool *xz_present_p) const
172 {
173 if (xz_present_p)
174 *xz_present_p = false;
175 return 1;
176 }
177 virtual bool
178 concat_get_ctrl(sc_digit *dst_p, int low_i) const
179 {
180 int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
181 int word_i = low_i / BITS_PER_DIGIT;
182
183 dst_p[word_i] &= ~bit_mask;
184 return false;
185 }
186 virtual bool
187 concat_get_data(sc_digit *dst_p, int low_i) const
188 {
189 bool non_zero;
190 int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
191 int word_i = low_i / BITS_PER_DIGIT;
192
193 if (operator uint64()) {
194 dst_p[word_i] |= bit_mask;
195 non_zero = true;
196 } else {
197 dst_p[word_i] &= ~bit_mask;
198 non_zero = false;
199 }
200 return non_zero;
201 }
202 virtual uint64
203 concat_get_uint64() const
204 {
205 return operator uint64();
206 }
207
208
209 // implicit conversions
210 operator uint64 () const;
211 bool operator ! () const;
212 bool operator ~ () const;
213
214
215 // explicit conversions
216 uint64 value() const { return operator uint64(); }
217
218 bool to_bool() const { return operator uint64(); }
219
220
221 // other methods
222 void print(::std::ostream& os=::std::cout) const { os << to_bool(); }
223
224 protected:
225 int m_index;
226 sc_int_base *m_obj_p;
227
228 private:
229 // Disabled
230 sc_int_bitref_r &operator = (const sc_int_bitref_r &);
231};
232
233
234inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &);
235
236
237// ----------------------------------------------------------------------------
238// CLASS : sc_int_bitref
239//
240// Proxy class for sc_int bit selection (r-value and l-value).
241// ----------------------------------------------------------------------------
242
243class sc_int_bitref : public sc_int_bitref_r
244{
245 friend class sc_int_base;
246 friend class sc_core::sc_vpool<sc_int_bitref>;
247
248 // constructor
249 sc_int_bitref() : sc_int_bitref_r() {}
250
251 public:
252 // copy constructor
253 sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {}
254
255 // assignment operators
256 sc_int_bitref &operator = (const sc_int_bitref_r &b);
257 sc_int_bitref &operator = (const sc_int_bitref &b);
258 sc_int_bitref &operator = (bool b);
259
260 sc_int_bitref &operator &= (bool b);
261 sc_int_bitref &operator |= (bool b);
262 sc_int_bitref &operator ^= (bool b);
263
264 // concatenation methods
265 virtual void concat_set(int64 src, int low_i);
266 virtual void concat_set(const sc_signed &src, int low_i);
267 virtual void concat_set(const sc_unsigned &src, int low_i);
268 virtual void concat_set(uint64 src, int low_i);
269
270 // other methods
271 void scan(::std::istream &is=::std::cin);
272
273 public:
274 static sc_core::sc_vpool<sc_int_bitref> m_pool;
275};
276
277
278
279inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &);
280
281
282// ----------------------------------------------------------------------------
283// CLASS : sc_int_subref_r
284//
285// Proxy class for sc_int part selection (r-value only).
286// ----------------------------------------------------------------------------
287
288class sc_int_subref_r : public sc_value_base
289{
290 friend class sc_int_base;
291 friend class sc_int_signal;
292 friend class sc_int_subref;
293
294 protected:
295 // constructor
296 sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {}
297
298 // initializer for sc_core::sc_vpool:
299 void initialize( const sc_int_base *obj_p, int left_i, int right_i)
300 {
301 m_obj_p = (sc_int_base *)obj_p;
302 m_left = left_i;
303 m_right = right_i;
304 }
305
306 public:
307 // copy constructor
308 sc_int_subref_r(const sc_int_subref_r &a) :
309 sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p),
310 m_right(a.m_right)
311 {}
312
313 // destructor
314 virtual ~sc_int_subref_r() {}
315
316 // capacity
317 int length() const { return (m_left - m_right + 1); }
318
319 // concatenation support
320 virtual int
321 concat_length(bool *xz_present_p) const
322 {
323 if (xz_present_p)
324 *xz_present_p = false;
325 return length();
326 }
327 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
328 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
329 virtual uint64
330 concat_get_uint64() const
331 {
332 int len = length();
333 uint64 val = operator uint_type();
334 if (len < 64)
335 return (uint64)(val & ~((uint_type)-1 << len));
336 else
337 return (uint64)val;
338 }
339
340 // reduce methods
341 bool and_reduce() const;
342 bool nand_reduce() const { return !and_reduce(); }
343 bool or_reduce() const;
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_int_base.h -- A signed integer whose length is less than 64 bit.
23
24 Unlike arbitrary precision, arithmetic and bitwise operations
25 are performed using the native types (hence capped at 64 bits).
26 The sc_int integer is useful when the user does not need
27 arbitrary precision and the performance is superior to
28 sc_bigint/sc_biguint.
29
30 Original Author: Amit Rao, Synopsys, Inc.
31
32 *****************************************************************************/
33
34/*****************************************************************************
35
36 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
37 changes you are making here.
38
39 Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
40 Description of Modification: - Resolved ambiguity with sc_(un)signed.
41 - Merged the code for 64- and 32-bit versions
42 via the constants in sc_nbdefs.h.
43 - Eliminated redundant file inclusions.
44
45 Name, Affiliation, Date:
46 Description of Modification:
47
48 *****************************************************************************/
49
50// $Log: sc_int_base.h,v $
51// Revision 1.3 2011/08/24 22:05:45 acg
52// Torsten Maehne: initialization changes to remove warnings.
53//
54// Revision 1.2 2011/02/18 20:19:15 acg
55// Andy Goodrich: updating Copyright notice.
56//
57// Revision 1.1.1.1 2006/12/15 20:20:05 acg
58// SystemC 2.3
59//
60// Revision 1.4 2006/05/08 17:50:01 acg
61// Andy Goodrich: Added David Long's declarations for friend operators,
62// functions, and methods, to keep the Microsoft compiler happy.
63//
64// Revision 1.3 2006/01/13 18:49:31 acg
65// Added $Log command so that CVS check in comments are reproduced in the
66// source.
67//
68
69#ifndef __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
70#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
71
72#include <iostream>
73
74#include "../misc/sc_value_base.hh"
75#include "../sc_temporary.hh"
76#include "sc_length_param.hh"
77#include "sc_nbdefs.hh"
78#include "sc_uint_base.hh"
79
80namespace sc_dt
81{
82
83class sc_concatref;
84
85// classes defined in this module
86class sc_int_bitref_r;
87class sc_int_bitref;
88class sc_int_subref_r;
89class sc_int_subref;
90class sc_int_base;
91class sc_signed_subref_r;
92class sc_unsigned_subref_r;
93
94// forward class declarations
95class sc_bv_base;
96class sc_lv_base;
97class sc_signed;
98class sc_unsigned;
99class sc_fxval;
100class sc_fxval_fast;
101class sc_fxnum;
102class sc_fxnum_fast;
103
104} // namespace sc_dt
105
106// extern template instantiations
107namespace sc_core
108{
109
110extern template class sc_vpool<sc_dt::sc_int_bitref>;
111extern template class sc_vpool<sc_dt::sc_int_subref>;
112
113} // namespace sc_core
114
115namespace sc_dt
116{
117
118extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
119
120// friend operator declarations
121
122// relational operators
123
124inline bool operator == (const sc_int_base &a, const sc_int_base &b);
125inline bool operator != (const sc_int_base &a, const sc_int_base &b);
126inline bool operator < (const sc_int_base &a, const sc_int_base &b);
127inline bool operator <= (const sc_int_base &a, const sc_int_base &b);
128inline bool operator > (const sc_int_base &a, const sc_int_base &b);
129inline bool operator >= (const sc_int_base &a, const sc_int_base &b);
130
131
132// ----------------------------------------------------------------------------
133// CLASS : sc_int_bitref_r
134//
135// Proxy class for sc_int bit selection (r-value only).
136// ----------------------------------------------------------------------------
137
138class sc_int_bitref_r : public sc_value_base
139{
140 friend class sc_int_base;
141
142 protected:
143 // constructor
144 sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {}
145
146 // initializer for sc_core::sc_vpool:
147 void initialize(const sc_int_base *obj_p, int index_)
148 {
149 m_obj_p = (sc_int_base *)obj_p;
150 m_index = index_;
151 }
152
153 public:
154 // copy constructor
155 sc_int_bitref_r(const sc_int_bitref_r &a) :
156 sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
157 {}
158
159 // destructor
160 virtual ~sc_int_bitref_r() {}
161
162 // capacity
163 int length() const { return 1; }
164
165#ifdef SC_DT_DEPRECATED
166 int bitwidth() const { return length(); }
167#endif
168
169 // concatenation support
170 virtual int
171 concat_length(bool *xz_present_p) const
172 {
173 if (xz_present_p)
174 *xz_present_p = false;
175 return 1;
176 }
177 virtual bool
178 concat_get_ctrl(sc_digit *dst_p, int low_i) const
179 {
180 int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
181 int word_i = low_i / BITS_PER_DIGIT;
182
183 dst_p[word_i] &= ~bit_mask;
184 return false;
185 }
186 virtual bool
187 concat_get_data(sc_digit *dst_p, int low_i) const
188 {
189 bool non_zero;
190 int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
191 int word_i = low_i / BITS_PER_DIGIT;
192
193 if (operator uint64()) {
194 dst_p[word_i] |= bit_mask;
195 non_zero = true;
196 } else {
197 dst_p[word_i] &= ~bit_mask;
198 non_zero = false;
199 }
200 return non_zero;
201 }
202 virtual uint64
203 concat_get_uint64() const
204 {
205 return operator uint64();
206 }
207
208
209 // implicit conversions
210 operator uint64 () const;
211 bool operator ! () const;
212 bool operator ~ () const;
213
214
215 // explicit conversions
216 uint64 value() const { return operator uint64(); }
217
218 bool to_bool() const { return operator uint64(); }
219
220
221 // other methods
222 void print(::std::ostream& os=::std::cout) const { os << to_bool(); }
223
224 protected:
225 int m_index;
226 sc_int_base *m_obj_p;
227
228 private:
229 // Disabled
230 sc_int_bitref_r &operator = (const sc_int_bitref_r &);
231};
232
233
234inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &);
235
236
237// ----------------------------------------------------------------------------
238// CLASS : sc_int_bitref
239//
240// Proxy class for sc_int bit selection (r-value and l-value).
241// ----------------------------------------------------------------------------
242
243class sc_int_bitref : public sc_int_bitref_r
244{
245 friend class sc_int_base;
246 friend class sc_core::sc_vpool<sc_int_bitref>;
247
248 // constructor
249 sc_int_bitref() : sc_int_bitref_r() {}
250
251 public:
252 // copy constructor
253 sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {}
254
255 // assignment operators
256 sc_int_bitref &operator = (const sc_int_bitref_r &b);
257 sc_int_bitref &operator = (const sc_int_bitref &b);
258 sc_int_bitref &operator = (bool b);
259
260 sc_int_bitref &operator &= (bool b);
261 sc_int_bitref &operator |= (bool b);
262 sc_int_bitref &operator ^= (bool b);
263
264 // concatenation methods
265 virtual void concat_set(int64 src, int low_i);
266 virtual void concat_set(const sc_signed &src, int low_i);
267 virtual void concat_set(const sc_unsigned &src, int low_i);
268 virtual void concat_set(uint64 src, int low_i);
269
270 // other methods
271 void scan(::std::istream &is=::std::cin);
272
273 public:
274 static sc_core::sc_vpool<sc_int_bitref> m_pool;
275};
276
277
278
279inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &);
280
281
282// ----------------------------------------------------------------------------
283// CLASS : sc_int_subref_r
284//
285// Proxy class for sc_int part selection (r-value only).
286// ----------------------------------------------------------------------------
287
288class sc_int_subref_r : public sc_value_base
289{
290 friend class sc_int_base;
291 friend class sc_int_signal;
292 friend class sc_int_subref;
293
294 protected:
295 // constructor
296 sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {}
297
298 // initializer for sc_core::sc_vpool:
299 void initialize( const sc_int_base *obj_p, int left_i, int right_i)
300 {
301 m_obj_p = (sc_int_base *)obj_p;
302 m_left = left_i;
303 m_right = right_i;
304 }
305
306 public:
307 // copy constructor
308 sc_int_subref_r(const sc_int_subref_r &a) :
309 sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p),
310 m_right(a.m_right)
311 {}
312
313 // destructor
314 virtual ~sc_int_subref_r() {}
315
316 // capacity
317 int length() const { return (m_left - m_right + 1); }
318
319 // concatenation support
320 virtual int
321 concat_length(bool *xz_present_p) const
322 {
323 if (xz_present_p)
324 *xz_present_p = false;
325 return length();
326 }
327 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
328 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
329 virtual uint64
330 concat_get_uint64() const
331 {
332 int len = length();
333 uint64 val = operator uint_type();
334 if (len < 64)
335 return (uint64)(val & ~((uint_type)-1 << len));
336 else
337 return (uint64)val;
338 }
339
340 // reduce methods
341 bool and_reduce() const;
342 bool nand_reduce() const { return !and_reduce(); }
343 bool or_reduce() const;
344 bool nor_reduce() const { return or_reduce(); }
344 bool nor_reduce() const { return !or_reduce(); }
345 bool xor_reduce() const;
345 bool xor_reduce() const;
346 bool xnor_reduce() const { return xor_reduce(); }
346 bool xnor_reduce() const { return !xor_reduce(); }
347
348 // implicit conversion to uint_type
349 operator uint_type () const;
350
351 // explicit conversions
352 uint_type value() const { return operator uint_type(); }
353
354
355 int to_int() const;
356 unsigned int to_uint() const;
357 long to_long() const;
358 unsigned long to_ulong() const;
359 int64 to_int64() const;
360 uint64 to_uint64() const;
361 double to_double() const;
362
363 // explicit conversion to character string
364 const std::string to_string(sc_numrep numrep=SC_DEC) const;
365 const std::string to_string(sc_numrep numrep, bool w_prefix) const;
366
367 // other methods
368 void
369 print(::std::ostream &os=::std::cout) const
370 {
371 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
372 }
373
374 protected:
375 int m_left;
376 sc_int_base *m_obj_p;
377 int m_right;
378
379 private:
380 const sc_int_subref_r &operator = (const sc_int_subref_r &);
381};
382
383inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &);
384
385
386// ----------------------------------------------------------------------------
387// CLASS : sc_int_subref
388//
389// Proxy class for sc_int part selection (r-value and l-value).
390// ----------------------------------------------------------------------------
391
392class sc_int_subref : public sc_int_subref_r
393{
394 friend class sc_int_base;
395 friend class sc_core::sc_vpool<sc_int_subref>;
396
397 protected:
398 // constructor
399 sc_int_subref() : sc_int_subref_r() {}
400
401 public:
402 // copy constructor
403 sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {}
404
405 // assignment operators
406 sc_int_subref &operator = (int_type v);
407 sc_int_subref &operator = (const sc_int_base &a);
408
409 sc_int_subref &
410 operator = (const sc_int_subref_r &a)
411 {
412 return operator = (a.operator uint_type());
413 }
414
415 sc_int_subref &
416 operator = (const sc_int_subref &a)
417 {
418 return operator = (a.operator uint_type());
419 }
420
421 template< class T >
422 sc_int_subref &
423 operator = (const sc_generic_base<T> &a)
424 {
425 return operator = (a->to_int64());
426 }
427
428 sc_int_subref &operator = (const char *a);
429
430 sc_int_subref &
431 operator = (unsigned long a)
432 {
433 return operator = ((int_type)a);
434 }
435
436 sc_int_subref &
437 operator = (long a)
438 {
439 return operator = ((int_type)a);
440 }
441
442 sc_int_subref &
443 operator = (unsigned int a)
444 {
445 return operator = ((int_type)a);
446 }
447
448 sc_int_subref &
449 operator = (int a)
450 {
451 return operator = ((int_type)a);
452 }
453
454 sc_int_subref &
455 operator = (uint64 a)
456 {
457 return operator = ((int_type)a);
458 }
459
460 sc_int_subref &
461 operator = (double a)
462 {
463 return operator = ((int_type)a);
464 }
465
466 sc_int_subref &operator = (const sc_signed &);
467 sc_int_subref &operator = (const sc_unsigned &);
468 sc_int_subref &operator = (const sc_bv_base &);
469 sc_int_subref &operator = (const sc_lv_base &);
470
471 // concatenation methods
472 virtual void concat_set(int64 src, int low_i);
473 virtual void concat_set(const sc_signed &src, int low_i);
474 virtual void concat_set(const sc_unsigned &src, int low_i);
475 virtual void concat_set(uint64 src, int low_i);
476
477 // other methods
478 void scan(::std::istream &is=::std::cin);
479
480 public:
481 static sc_core::sc_vpool<sc_int_subref> m_pool;
482};
483
484
485inline ::std::istream &operator >> (::std::istream &, sc_int_subref &);
486
487
488// ----------------------------------------------------------------------------
489// CLASS : sc_int_base
490//
491// Base class for sc_int.
492// ----------------------------------------------------------------------------
493
494class sc_int_base : public sc_value_base
495{
496 friend class sc_int_bitref_r;
497 friend class sc_int_bitref;
498 friend class sc_int_subref_r;
499 friend class sc_int_subref;
500
501
502 // support methods
503 void invalid_length() const;
504 void invalid_index(int i) const;
505 void invalid_range(int l, int r) const;
506
507 void
508 check_length() const
509 {
510 if (m_len <= 0 || m_len > SC_INTWIDTH) {
511 invalid_length();
512 }
513 }
514
515 void
516 check_index(int i) const
517 {
518 if (i < 0 || i >= m_len) {
519 invalid_index(i);
520 }
521 }
522
523 void
524 check_range(int l, int r) const
525 {
526 if (r < 0 || l >= m_len || l < r) {
527 invalid_range(l, r);
528 }
529 }
530
531 void check_value() const;
532
533 void
534 extend_sign()
535 {
536#ifdef DEBUG_SYSTEMC
537 check_value();
538#endif
539 m_val = (m_val << m_ulen >> m_ulen);
540 }
541
542public:
543
544 // constructors
545 explicit sc_int_base(int w=sc_length_param().len()) :
546 m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len)
547 {
548 check_length();
549 }
550
551 sc_int_base(int_type v, int w) :
552 m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len)
553 {
554 check_length();
555 extend_sign();
556 }
557
558 sc_int_base(const sc_int_base &a) :
559 sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
560 {}
561
562 explicit sc_int_base(const sc_int_subref_r &a) :
563 m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
564 {
565 extend_sign();
566 }
567
568 template< class T >
569 explicit sc_int_base(const sc_generic_base<T> &a) :
570 m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len)
571 {
572 check_length();
573 extend_sign();
574 }
575
576 explicit sc_int_base(const sc_signed &a);
577 explicit sc_int_base(const sc_unsigned &a);
578 explicit sc_int_base(const sc_bv_base &v);
579 explicit sc_int_base(const sc_lv_base &v);
580 explicit sc_int_base(const sc_uint_subref_r &v);
581 explicit sc_int_base(const sc_signed_subref_r &v);
582 explicit sc_int_base(const sc_unsigned_subref_r &v);
583
584
585 // destructor
586 virtual ~sc_int_base() {}
587
588 // assignment operators
589 sc_int_base &
590 operator = (int_type v)
591 {
592 m_val = v;
593 extend_sign();
594 return *this;
595 }
596
597 sc_int_base &
598 operator = (const sc_int_base &a)
599 {
600 m_val = a.m_val;
601 extend_sign();
602 return *this;
603 }
604
605 sc_int_base &
606 operator = (const sc_int_subref_r &a)
607 {
608 m_val = a;
609 extend_sign();
610 return *this;
611 }
612
613 template<class T>
614 sc_int_base &
615 operator = (const sc_generic_base<T> &a)
616 {
617 m_val = a->to_int64();
618 extend_sign();
619 return *this;
620 }
621
622 sc_int_base &operator = (const sc_signed &a);
623 sc_int_base &operator = (const sc_unsigned &a);
624
625 sc_int_base &operator = (const sc_fxval &a);
626 sc_int_base &operator = (const sc_fxval_fast &a);
627 sc_int_base &operator = (const sc_fxnum &a);
628 sc_int_base &operator = (const sc_fxnum_fast &a);
629
630 sc_int_base &operator = (const sc_bv_base &a);
631 sc_int_base &operator = (const sc_lv_base &a);
632
633 sc_int_base &operator = (const char *a);
634
635 sc_int_base &
636 operator = (unsigned long a)
637 {
638 m_val = a;
639 extend_sign();
640 return *this;
641 }
642
643 sc_int_base &
644 operator = (long a)
645 {
646 m_val = a;
647 extend_sign();
648 return *this;
649 }
650
651 sc_int_base &
652 operator = (unsigned int a)
653 {
654 m_val = a;
655 extend_sign();
656 return *this;
657 }
658
659 sc_int_base &
660 operator = (int a)
661 {
662 m_val = a;
663 extend_sign();
664 return *this;
665 }
666
667 sc_int_base &
668 operator = (uint64 a)
669 {
670 m_val = a;
671 extend_sign();
672 return *this;
673 }
674
675 sc_int_base &
676 operator = (double a)
677 {
678 m_val = (int_type)a;
679 extend_sign();
680 return *this;
681 }
682
683 // arithmetic assignment operators
684 sc_int_base &
685 operator += (int_type v)
686 {
687 m_val += v;
688 extend_sign();
689 return *this;
690 }
691
692 sc_int_base &
693 operator -= (int_type v)
694 {
695 m_val -= v;
696 extend_sign();
697 return *this;
698 }
699
700 sc_int_base &
701 operator *= (int_type v)
702 {
703 m_val *= v;
704 extend_sign();
705 return *this;
706 }
707
708 sc_int_base &
709 operator /= (int_type v)
710 {
711 m_val /= v;
712 extend_sign();
713 return *this;
714 }
715
716 sc_int_base &
717 operator %= (int_type v)
718 {
719 m_val %= v;
720 extend_sign();
721 return *this;
722 }
723
724
725 // bitwise assignment operators
726 sc_int_base &
727 operator &= (int_type v)
728 {
729 m_val &= v;
730 extend_sign();
731 return *this;
732 }
733
734 sc_int_base &
735 operator |= (int_type v)
736 {
737 m_val |= v;
738 extend_sign();
739 return *this;
740 }
741
742 sc_int_base &
743 operator ^= (int_type v)
744 {
745 m_val ^= v;
746 extend_sign();
747 return *this;
748 }
749
750
751 sc_int_base &
752 operator <<= (int_type v)
753 {
754 m_val <<= v;
755 extend_sign();
756 return *this;
757 }
758
759 sc_int_base &
760 operator >>= (int_type v)
761 {
762 m_val >>= v;
763 /* no sign extension needed */
764 return *this;
765 }
766
767
768 // prefix and postfix increment and decrement operators
769 sc_int_base &
770 operator ++ () // prefix
771 {
772 ++m_val;
773 extend_sign();
774 return *this;
775 }
776
777 const sc_int_base
778 operator ++ (int) // postfix
779 {
780 sc_int_base tmp(*this);
781 ++m_val;
782 extend_sign();
783 return tmp;
784 }
785
786 sc_int_base &
787 operator -- () // prefix
788 {
789 --m_val;
790 extend_sign();
791 return *this;
792 }
793
794 const sc_int_base
795 operator -- ( int ) // postfix
796 {
797 sc_int_base tmp(*this);
798 --m_val;
799 extend_sign();
800 return tmp;
801 }
802
803
804 // relational operators
805 friend bool
806 operator == (const sc_int_base &a, const sc_int_base &b)
807 {
808 return a.m_val == b.m_val;
809 }
810
811 friend bool
812 operator != (const sc_int_base &a, const sc_int_base &b)
813 {
814 return a.m_val != b.m_val;
815 }
816
817 friend bool
818 operator < (const sc_int_base &a, const sc_int_base &b)
819 {
820 return a.m_val < b.m_val;
821 }
822
823 friend bool
824 operator <= (const sc_int_base &a, const sc_int_base &b)
825 {
826 return a.m_val <= b.m_val;
827 }
828
829 friend bool
830 operator > (const sc_int_base &a, const sc_int_base &b)
831 {
832 return a.m_val > b.m_val;
833 }
834
835 friend bool
836 operator >= (const sc_int_base &a, const sc_int_base &b)
837 {
838 return a.m_val >= b.m_val;
839 }
840
841
842 // bit selection
843 sc_int_bitref &operator [] (int i);
844 const sc_int_bitref_r &operator [] (int i) const;
845
846 sc_int_bitref &bit(int i);
847 const sc_int_bitref_r &bit(int i) const;
848
849
850 // part selection
851 sc_int_subref &operator () (int left, int right);
852 const sc_int_subref_r &operator () (int left, int right) const;
853
854 sc_int_subref &range(int left, int right);
855 const sc_int_subref_r &range(int left, int right) const;
856
857
858 // bit access, without bounds checking or sign extension
859 bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); }
860
861 void set(int i) { m_val |= (UINT_ONE << i); }
862
863 void
864 set(int i, bool v)
865 {
866 v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i);
867 }
868
869 // capacity
870 int length() const { return m_len; }
871
872 // concatenation support
873 virtual int
874 concat_length(bool* xz_present_p) const
875 {
876 if (xz_present_p)
877 *xz_present_p = false;
878 return length();
879 }
880 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
881 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
882 virtual uint64
883 concat_get_uint64() const
884 {
885 if (m_len < 64)
886 return (uint64)(m_val & ~((uint_type) - 1 << m_len));
887 else
888 return (uint64)m_val;
889 }
890 virtual void concat_set(int64 src, int low_i);
891 virtual void concat_set(const sc_signed &src, int low_i);
892 virtual void concat_set(const sc_unsigned &src, int low_i);
893 virtual void concat_set(uint64 src, int low_i);
894
895
896 // reduce methods
897 bool and_reduce() const;
898 bool nand_reduce() const { return !and_reduce(); }
899 bool or_reduce() const;
900 bool nor_reduce() const { return !or_reduce(); }
901 bool xor_reduce() const;
902 bool xnor_reduce() const { return !xor_reduce(); }
903
904
905 // implicit conversion to int_type
906 operator int_type() const { return m_val; }
907
908
909 // explicit conversions
910 int_type value() const { return operator int_type(); }
911 int to_int() const { return (int)m_val; }
912 unsigned int to_uint() const { return (unsigned int)m_val; }
913 long to_long() const { return (long)m_val; }
914 unsigned long to_ulong() const { return (unsigned long)m_val; }
915 int64 to_int64() const { return (int64)m_val; }
916 uint64 to_uint64() const { return (uint64)m_val; }
917 double to_double() const { return (double)m_val; }
918 long long_low() const { return (long)(m_val & UINT64_32ONES); }
919 long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); }
920
921
922 // explicit conversion to character string
923 const std::string to_string(sc_numrep numrep=SC_DEC) const;
924 const std::string to_string(sc_numrep numrep, bool w_prefix) const;
925
926
927 // other methods
928 void
929 print(::std::ostream &os=::std::cout) const
930 {
931 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
932 }
933
934 void scan(::std::istream &is=::std::cin);
935
936 protected:
937 int_type m_val; // value
938 int m_len; // length
939 int m_ulen; // unused length
940};
941
942inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &);
943inline ::std::istream &operator >> (::std::istream &, sc_int_base &);
944
945
946// ----------------------------------------------------------------------------
947// CLASS : sc_int_bitref_r
948//
949// Proxy class for sc_int bit selection (r-value only).
950// ----------------------------------------------------------------------------
951
952// implicit conversion to uint64
953
954inline sc_int_bitref_r::operator uint64 () const
955{
956 return m_obj_p->test(m_index);
957}
958
959inline bool
960sc_int_bitref_r::operator ! () const
961{
962 return ! m_obj_p->test(m_index);
963}
964
965inline bool
966sc_int_bitref_r::operator ~ () const
967{
968 return !m_obj_p->test(m_index);
969}
970
971
972inline ::std::ostream &
973operator << (::std::ostream &os, const sc_int_bitref_r &a)
974{
975 a.print(os);
976 return os;
977}
978
979
980// ----------------------------------------------------------------------------
981// CLASS : sc_int_bitref
982//
983// Proxy class for sc_int bit selection (r-value and l-value).
984// ----------------------------------------------------------------------------
985
986// assignment operators
987
988inline sc_int_bitref &
989sc_int_bitref::operator = (const sc_int_bitref_r &b)
990{
991 m_obj_p->set(m_index, (bool)b);
992 m_obj_p->extend_sign();
993 return *this;
994}
995
996inline sc_int_bitref &
997sc_int_bitref::operator = (const sc_int_bitref &b)
998{
999 m_obj_p->set(m_index, (bool)b);
1000 m_obj_p->extend_sign();
1001 return *this;
1002}
1003
1004inline sc_int_bitref &
1005sc_int_bitref::operator = (bool b)
1006{
1007 m_obj_p->set(m_index, b);
1008 m_obj_p->extend_sign();
1009 return *this;
1010}
1011
1012
1013inline sc_int_bitref &
1014sc_int_bitref::operator &= (bool b)
1015{
1016 if (!b) {
1017 m_obj_p->set(m_index, b);
1018 m_obj_p->extend_sign();
1019 }
1020 return *this;
1021}
1022
1023inline sc_int_bitref &
1024sc_int_bitref::operator |= (bool b)
1025{
1026 if (b) {
1027 m_obj_p->set(m_index, b);
1028 m_obj_p->extend_sign();
1029 }
1030 return *this;
1031}
1032
1033inline sc_int_bitref &
1034sc_int_bitref::operator ^= (bool b)
1035{
1036 if (b) {
1037 m_obj_p->m_val ^= (UINT_ONE << m_index);
1038 m_obj_p->extend_sign();
1039 }
1040 return *this;
1041}
1042
1043
1044
1045inline ::std::istream &
1046operator >> (::std::istream &is, sc_int_bitref &a)
1047{
1048 a.scan(is);
1049 return is;
1050}
1051
1052
1053// ----------------------------------------------------------------------------
1054// CLASS : sc_int_subref_r
1055//
1056// Proxy class for sc_int part selection (r-value only).
1057// ----------------------------------------------------------------------------
1058
1059// implicit conversion to int_type
1060
1061inline sc_int_subref_r::operator uint_type() const
1062{
1063 uint_type /*int_type*/ val = m_obj_p->m_val;
1064 int uleft = SC_INTWIDTH - (m_left + 1);
1065 int uright = uleft + m_right;
1066 return (val << uleft >> uright);
1067}
1068
1069
1070// reduce methods
1071
1072inline bool
1073sc_int_subref_r::and_reduce() const
1074{
1075 sc_int_base a(*this);
1076 return a.and_reduce();
1077}
1078
1079inline bool
1080sc_int_subref_r::or_reduce() const
1081{
1082 sc_int_base a(*this);
1083 return a.or_reduce();
1084}
1085
1086inline bool
1087sc_int_subref_r::xor_reduce() const
1088{
1089 sc_int_base a(*this);
1090 return a.xor_reduce();
1091}
1092
1093
1094// explicit conversions
1095
1096inline int
1097sc_int_subref_r::to_int() const
1098{
1099 int result = static_cast<int>(operator uint_type());
1100 return result;
1101}
1102
1103inline unsigned int
1104sc_int_subref_r::to_uint() const
1105{
1106 unsigned int result = static_cast<unsigned int>(operator uint_type());
1107 return result;
1108}
1109
1110inline long
1111sc_int_subref_r::to_long() const
1112{
1113 long result = static_cast<long>(operator uint_type());
1114 return result;
1115}
1116
1117inline unsigned long
1118sc_int_subref_r::to_ulong() const
1119{
1120 unsigned long result = static_cast<unsigned long>(operator uint_type());
1121 return result;
1122}
1123
1124inline int64
1125sc_int_subref_r::to_int64() const
1126{
1127 int64 result = operator uint_type();
1128 return result;
1129}
1130
1131inline uint64
1132sc_int_subref_r::to_uint64() const
1133{
1134 uint64 result = operator uint_type();
1135 return result;
1136}
1137
1138inline double
1139sc_int_subref_r::to_double() const
1140{
1141 double result = static_cast<double>(operator uint_type());
1142 return result;
1143}
1144
1145
1146// explicit conversion to character string
1147
1148inline const std::string
1149sc_int_subref_r::to_string(sc_numrep numrep) const
1150{
1151 sc_uint_base a(length());
1152 a = operator uint_type();
1153 return a.to_string(numrep);
1154}
1155
1156inline const std::string
1157sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
1158{
1159 sc_uint_base a(length());
1160 a = operator uint_type();
1161 return a.to_string(numrep, w_prefix);
1162}
1163
1164
1165// functional notation for the reduce methods
1166
1167inline bool
1168and_reduce(const sc_int_subref_r &a)
1169{
1170 return a.and_reduce();
1171}
1172
1173inline bool
1174nand_reduce(const sc_int_subref_r &a)
1175{
1176 return a.nand_reduce();
1177}
1178
1179inline bool
1180or_reduce(const sc_int_subref_r &a)
1181{
1182 return a.or_reduce();
1183}
1184
1185inline bool
1186nor_reduce(const sc_int_subref_r &a)
1187{
1188 return a.nor_reduce();
1189}
1190
1191inline bool
1192xor_reduce(const sc_int_subref_r &a)
1193{
1194 return a.xor_reduce();
1195}
1196
1197inline bool
1198xnor_reduce(const sc_int_subref_r &a)
1199{
1200 return a.xnor_reduce();
1201}
1202
1203
1204
1205inline ::std::ostream &
1206operator << (::std::ostream &os, const sc_int_subref_r &a)
1207{
1208 a.print(os);
1209 return os;
1210}
1211
1212
1213// ----------------------------------------------------------------------------
1214// CLASS : sc_int_subref
1215//
1216// Proxy class for sc_int part selection (r-value and l-value).
1217// ----------------------------------------------------------------------------
1218
1219// assignment operators
1220
1221inline sc_int_subref &
1222sc_int_subref::operator = (const sc_int_base &a)
1223{
1224 return operator = (a.operator int_type());
1225}
1226
1227inline sc_int_subref &
1228sc_int_subref::operator = (const char *a)
1229{
1230 sc_int_base aa(length());
1231 return (*this = aa = a);
1232}
1233
1234
1235
1236inline ::std::istream &
1237operator >> (::std::istream &is, sc_int_subref &a)
1238{
1239 a.scan(is);
1240 return is;
1241}
1242
1243
1244// ----------------------------------------------------------------------------
1245// CLASS : sc_int_base
1246//
1247// Base class for sc_int.
1248// ----------------------------------------------------------------------------
1249
1250// bit selection
1251
1252inline sc_int_bitref &
1253sc_int_base::operator [] (int i)
1254{
1255 check_index(i);
1256 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1257 result_p->initialize(this, i);
1258 return *result_p;
1259}
1260
1261inline const sc_int_bitref_r &
1262sc_int_base::operator [] (int i) const
1263{
1264 check_index(i);
1265 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1266 result_p->initialize(this, i);
1267 return *result_p;
1268}
1269
1270
1271inline sc_int_bitref &
1272sc_int_base::bit(int i)
1273{
1274 check_index(i);
1275 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1276 result_p->initialize(this, i);
1277 return *result_p;
1278}
1279
1280inline const sc_int_bitref_r &
1281sc_int_base::bit(int i) const
1282{
1283 check_index(i);
1284 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1285 result_p->initialize(this, i);
1286 return *result_p;
1287}
1288
1289
1290// part selection
1291
1292inline sc_int_subref &
1293sc_int_base::operator () (int left, int right)
1294{
1295 check_range(left, right);
1296 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1297 result_p->initialize(this, left, right);
1298 return *result_p;
1299}
1300
1301inline const sc_int_subref_r &
1302sc_int_base::operator () (int left, int right) const
1303{
1304 check_range(left, right);
1305 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1306 result_p->initialize(this, left, right);
1307 return *result_p;
1308}
1309
1310
1311inline sc_int_subref &
1312sc_int_base::range(int left, int right)
1313{
1314 check_range(left, right);
1315 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1316 result_p->initialize(this, left, right);
1317 return *result_p;
1318}
1319
1320inline const sc_int_subref_r &
1321sc_int_base::range(int left, int right) const
1322{
1323 check_range(left, right);
1324 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1325 result_p->initialize(this, left, right);
1326 return *result_p;
1327}
1328
1329
1330// functional notation for the reduce methods
1331
1332inline bool
1333and_reduce(const sc_int_base &a)
1334{
1335 return a.and_reduce();
1336}
1337
1338inline bool
1339nand_reduce(const sc_int_base &a)
1340{
1341 return a.nand_reduce();
1342}
1343
1344inline bool
1345or_reduce(const sc_int_base &a)
1346{
1347 return a.or_reduce();
1348}
1349
1350inline bool
1351nor_reduce(const sc_int_base &a)
1352{
1353 return a.nor_reduce();
1354}
1355
1356inline bool
1357xor_reduce(const sc_int_base &a)
1358{
1359 return a.xor_reduce();
1360}
1361
1362inline bool
1363xnor_reduce(const sc_int_base &a)
1364{
1365 return a.xnor_reduce();
1366}
1367
1368
1369
1370inline ::std::ostream &
1371operator << (::std::ostream &os, const sc_int_base &a)
1372{
1373 a.print(os);
1374 return os;
1375}
1376
1377inline ::std::istream &
1378operator >> (::std::istream &is, sc_int_base &a)
1379{
1380 a.scan(is);
1381 return is;
1382}
1383
1384} // namespace sc_dt
1385
1386#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
347
348 // implicit conversion to uint_type
349 operator uint_type () const;
350
351 // explicit conversions
352 uint_type value() const { return operator uint_type(); }
353
354
355 int to_int() const;
356 unsigned int to_uint() const;
357 long to_long() const;
358 unsigned long to_ulong() const;
359 int64 to_int64() const;
360 uint64 to_uint64() const;
361 double to_double() const;
362
363 // explicit conversion to character string
364 const std::string to_string(sc_numrep numrep=SC_DEC) const;
365 const std::string to_string(sc_numrep numrep, bool w_prefix) const;
366
367 // other methods
368 void
369 print(::std::ostream &os=::std::cout) const
370 {
371 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
372 }
373
374 protected:
375 int m_left;
376 sc_int_base *m_obj_p;
377 int m_right;
378
379 private:
380 const sc_int_subref_r &operator = (const sc_int_subref_r &);
381};
382
383inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &);
384
385
386// ----------------------------------------------------------------------------
387// CLASS : sc_int_subref
388//
389// Proxy class for sc_int part selection (r-value and l-value).
390// ----------------------------------------------------------------------------
391
392class sc_int_subref : public sc_int_subref_r
393{
394 friend class sc_int_base;
395 friend class sc_core::sc_vpool<sc_int_subref>;
396
397 protected:
398 // constructor
399 sc_int_subref() : sc_int_subref_r() {}
400
401 public:
402 // copy constructor
403 sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {}
404
405 // assignment operators
406 sc_int_subref &operator = (int_type v);
407 sc_int_subref &operator = (const sc_int_base &a);
408
409 sc_int_subref &
410 operator = (const sc_int_subref_r &a)
411 {
412 return operator = (a.operator uint_type());
413 }
414
415 sc_int_subref &
416 operator = (const sc_int_subref &a)
417 {
418 return operator = (a.operator uint_type());
419 }
420
421 template< class T >
422 sc_int_subref &
423 operator = (const sc_generic_base<T> &a)
424 {
425 return operator = (a->to_int64());
426 }
427
428 sc_int_subref &operator = (const char *a);
429
430 sc_int_subref &
431 operator = (unsigned long a)
432 {
433 return operator = ((int_type)a);
434 }
435
436 sc_int_subref &
437 operator = (long a)
438 {
439 return operator = ((int_type)a);
440 }
441
442 sc_int_subref &
443 operator = (unsigned int a)
444 {
445 return operator = ((int_type)a);
446 }
447
448 sc_int_subref &
449 operator = (int a)
450 {
451 return operator = ((int_type)a);
452 }
453
454 sc_int_subref &
455 operator = (uint64 a)
456 {
457 return operator = ((int_type)a);
458 }
459
460 sc_int_subref &
461 operator = (double a)
462 {
463 return operator = ((int_type)a);
464 }
465
466 sc_int_subref &operator = (const sc_signed &);
467 sc_int_subref &operator = (const sc_unsigned &);
468 sc_int_subref &operator = (const sc_bv_base &);
469 sc_int_subref &operator = (const sc_lv_base &);
470
471 // concatenation methods
472 virtual void concat_set(int64 src, int low_i);
473 virtual void concat_set(const sc_signed &src, int low_i);
474 virtual void concat_set(const sc_unsigned &src, int low_i);
475 virtual void concat_set(uint64 src, int low_i);
476
477 // other methods
478 void scan(::std::istream &is=::std::cin);
479
480 public:
481 static sc_core::sc_vpool<sc_int_subref> m_pool;
482};
483
484
485inline ::std::istream &operator >> (::std::istream &, sc_int_subref &);
486
487
488// ----------------------------------------------------------------------------
489// CLASS : sc_int_base
490//
491// Base class for sc_int.
492// ----------------------------------------------------------------------------
493
494class sc_int_base : public sc_value_base
495{
496 friend class sc_int_bitref_r;
497 friend class sc_int_bitref;
498 friend class sc_int_subref_r;
499 friend class sc_int_subref;
500
501
502 // support methods
503 void invalid_length() const;
504 void invalid_index(int i) const;
505 void invalid_range(int l, int r) const;
506
507 void
508 check_length() const
509 {
510 if (m_len <= 0 || m_len > SC_INTWIDTH) {
511 invalid_length();
512 }
513 }
514
515 void
516 check_index(int i) const
517 {
518 if (i < 0 || i >= m_len) {
519 invalid_index(i);
520 }
521 }
522
523 void
524 check_range(int l, int r) const
525 {
526 if (r < 0 || l >= m_len || l < r) {
527 invalid_range(l, r);
528 }
529 }
530
531 void check_value() const;
532
533 void
534 extend_sign()
535 {
536#ifdef DEBUG_SYSTEMC
537 check_value();
538#endif
539 m_val = (m_val << m_ulen >> m_ulen);
540 }
541
542public:
543
544 // constructors
545 explicit sc_int_base(int w=sc_length_param().len()) :
546 m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len)
547 {
548 check_length();
549 }
550
551 sc_int_base(int_type v, int w) :
552 m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len)
553 {
554 check_length();
555 extend_sign();
556 }
557
558 sc_int_base(const sc_int_base &a) :
559 sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
560 {}
561
562 explicit sc_int_base(const sc_int_subref_r &a) :
563 m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
564 {
565 extend_sign();
566 }
567
568 template< class T >
569 explicit sc_int_base(const sc_generic_base<T> &a) :
570 m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len)
571 {
572 check_length();
573 extend_sign();
574 }
575
576 explicit sc_int_base(const sc_signed &a);
577 explicit sc_int_base(const sc_unsigned &a);
578 explicit sc_int_base(const sc_bv_base &v);
579 explicit sc_int_base(const sc_lv_base &v);
580 explicit sc_int_base(const sc_uint_subref_r &v);
581 explicit sc_int_base(const sc_signed_subref_r &v);
582 explicit sc_int_base(const sc_unsigned_subref_r &v);
583
584
585 // destructor
586 virtual ~sc_int_base() {}
587
588 // assignment operators
589 sc_int_base &
590 operator = (int_type v)
591 {
592 m_val = v;
593 extend_sign();
594 return *this;
595 }
596
597 sc_int_base &
598 operator = (const sc_int_base &a)
599 {
600 m_val = a.m_val;
601 extend_sign();
602 return *this;
603 }
604
605 sc_int_base &
606 operator = (const sc_int_subref_r &a)
607 {
608 m_val = a;
609 extend_sign();
610 return *this;
611 }
612
613 template<class T>
614 sc_int_base &
615 operator = (const sc_generic_base<T> &a)
616 {
617 m_val = a->to_int64();
618 extend_sign();
619 return *this;
620 }
621
622 sc_int_base &operator = (const sc_signed &a);
623 sc_int_base &operator = (const sc_unsigned &a);
624
625 sc_int_base &operator = (const sc_fxval &a);
626 sc_int_base &operator = (const sc_fxval_fast &a);
627 sc_int_base &operator = (const sc_fxnum &a);
628 sc_int_base &operator = (const sc_fxnum_fast &a);
629
630 sc_int_base &operator = (const sc_bv_base &a);
631 sc_int_base &operator = (const sc_lv_base &a);
632
633 sc_int_base &operator = (const char *a);
634
635 sc_int_base &
636 operator = (unsigned long a)
637 {
638 m_val = a;
639 extend_sign();
640 return *this;
641 }
642
643 sc_int_base &
644 operator = (long a)
645 {
646 m_val = a;
647 extend_sign();
648 return *this;
649 }
650
651 sc_int_base &
652 operator = (unsigned int a)
653 {
654 m_val = a;
655 extend_sign();
656 return *this;
657 }
658
659 sc_int_base &
660 operator = (int a)
661 {
662 m_val = a;
663 extend_sign();
664 return *this;
665 }
666
667 sc_int_base &
668 operator = (uint64 a)
669 {
670 m_val = a;
671 extend_sign();
672 return *this;
673 }
674
675 sc_int_base &
676 operator = (double a)
677 {
678 m_val = (int_type)a;
679 extend_sign();
680 return *this;
681 }
682
683 // arithmetic assignment operators
684 sc_int_base &
685 operator += (int_type v)
686 {
687 m_val += v;
688 extend_sign();
689 return *this;
690 }
691
692 sc_int_base &
693 operator -= (int_type v)
694 {
695 m_val -= v;
696 extend_sign();
697 return *this;
698 }
699
700 sc_int_base &
701 operator *= (int_type v)
702 {
703 m_val *= v;
704 extend_sign();
705 return *this;
706 }
707
708 sc_int_base &
709 operator /= (int_type v)
710 {
711 m_val /= v;
712 extend_sign();
713 return *this;
714 }
715
716 sc_int_base &
717 operator %= (int_type v)
718 {
719 m_val %= v;
720 extend_sign();
721 return *this;
722 }
723
724
725 // bitwise assignment operators
726 sc_int_base &
727 operator &= (int_type v)
728 {
729 m_val &= v;
730 extend_sign();
731 return *this;
732 }
733
734 sc_int_base &
735 operator |= (int_type v)
736 {
737 m_val |= v;
738 extend_sign();
739 return *this;
740 }
741
742 sc_int_base &
743 operator ^= (int_type v)
744 {
745 m_val ^= v;
746 extend_sign();
747 return *this;
748 }
749
750
751 sc_int_base &
752 operator <<= (int_type v)
753 {
754 m_val <<= v;
755 extend_sign();
756 return *this;
757 }
758
759 sc_int_base &
760 operator >>= (int_type v)
761 {
762 m_val >>= v;
763 /* no sign extension needed */
764 return *this;
765 }
766
767
768 // prefix and postfix increment and decrement operators
769 sc_int_base &
770 operator ++ () // prefix
771 {
772 ++m_val;
773 extend_sign();
774 return *this;
775 }
776
777 const sc_int_base
778 operator ++ (int) // postfix
779 {
780 sc_int_base tmp(*this);
781 ++m_val;
782 extend_sign();
783 return tmp;
784 }
785
786 sc_int_base &
787 operator -- () // prefix
788 {
789 --m_val;
790 extend_sign();
791 return *this;
792 }
793
794 const sc_int_base
795 operator -- ( int ) // postfix
796 {
797 sc_int_base tmp(*this);
798 --m_val;
799 extend_sign();
800 return tmp;
801 }
802
803
804 // relational operators
805 friend bool
806 operator == (const sc_int_base &a, const sc_int_base &b)
807 {
808 return a.m_val == b.m_val;
809 }
810
811 friend bool
812 operator != (const sc_int_base &a, const sc_int_base &b)
813 {
814 return a.m_val != b.m_val;
815 }
816
817 friend bool
818 operator < (const sc_int_base &a, const sc_int_base &b)
819 {
820 return a.m_val < b.m_val;
821 }
822
823 friend bool
824 operator <= (const sc_int_base &a, const sc_int_base &b)
825 {
826 return a.m_val <= b.m_val;
827 }
828
829 friend bool
830 operator > (const sc_int_base &a, const sc_int_base &b)
831 {
832 return a.m_val > b.m_val;
833 }
834
835 friend bool
836 operator >= (const sc_int_base &a, const sc_int_base &b)
837 {
838 return a.m_val >= b.m_val;
839 }
840
841
842 // bit selection
843 sc_int_bitref &operator [] (int i);
844 const sc_int_bitref_r &operator [] (int i) const;
845
846 sc_int_bitref &bit(int i);
847 const sc_int_bitref_r &bit(int i) const;
848
849
850 // part selection
851 sc_int_subref &operator () (int left, int right);
852 const sc_int_subref_r &operator () (int left, int right) const;
853
854 sc_int_subref &range(int left, int right);
855 const sc_int_subref_r &range(int left, int right) const;
856
857
858 // bit access, without bounds checking or sign extension
859 bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); }
860
861 void set(int i) { m_val |= (UINT_ONE << i); }
862
863 void
864 set(int i, bool v)
865 {
866 v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i);
867 }
868
869 // capacity
870 int length() const { return m_len; }
871
872 // concatenation support
873 virtual int
874 concat_length(bool* xz_present_p) const
875 {
876 if (xz_present_p)
877 *xz_present_p = false;
878 return length();
879 }
880 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
881 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
882 virtual uint64
883 concat_get_uint64() const
884 {
885 if (m_len < 64)
886 return (uint64)(m_val & ~((uint_type) - 1 << m_len));
887 else
888 return (uint64)m_val;
889 }
890 virtual void concat_set(int64 src, int low_i);
891 virtual void concat_set(const sc_signed &src, int low_i);
892 virtual void concat_set(const sc_unsigned &src, int low_i);
893 virtual void concat_set(uint64 src, int low_i);
894
895
896 // reduce methods
897 bool and_reduce() const;
898 bool nand_reduce() const { return !and_reduce(); }
899 bool or_reduce() const;
900 bool nor_reduce() const { return !or_reduce(); }
901 bool xor_reduce() const;
902 bool xnor_reduce() const { return !xor_reduce(); }
903
904
905 // implicit conversion to int_type
906 operator int_type() const { return m_val; }
907
908
909 // explicit conversions
910 int_type value() const { return operator int_type(); }
911 int to_int() const { return (int)m_val; }
912 unsigned int to_uint() const { return (unsigned int)m_val; }
913 long to_long() const { return (long)m_val; }
914 unsigned long to_ulong() const { return (unsigned long)m_val; }
915 int64 to_int64() const { return (int64)m_val; }
916 uint64 to_uint64() const { return (uint64)m_val; }
917 double to_double() const { return (double)m_val; }
918 long long_low() const { return (long)(m_val & UINT64_32ONES); }
919 long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); }
920
921
922 // explicit conversion to character string
923 const std::string to_string(sc_numrep numrep=SC_DEC) const;
924 const std::string to_string(sc_numrep numrep, bool w_prefix) const;
925
926
927 // other methods
928 void
929 print(::std::ostream &os=::std::cout) const
930 {
931 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
932 }
933
934 void scan(::std::istream &is=::std::cin);
935
936 protected:
937 int_type m_val; // value
938 int m_len; // length
939 int m_ulen; // unused length
940};
941
942inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &);
943inline ::std::istream &operator >> (::std::istream &, sc_int_base &);
944
945
946// ----------------------------------------------------------------------------
947// CLASS : sc_int_bitref_r
948//
949// Proxy class for sc_int bit selection (r-value only).
950// ----------------------------------------------------------------------------
951
952// implicit conversion to uint64
953
954inline sc_int_bitref_r::operator uint64 () const
955{
956 return m_obj_p->test(m_index);
957}
958
959inline bool
960sc_int_bitref_r::operator ! () const
961{
962 return ! m_obj_p->test(m_index);
963}
964
965inline bool
966sc_int_bitref_r::operator ~ () const
967{
968 return !m_obj_p->test(m_index);
969}
970
971
972inline ::std::ostream &
973operator << (::std::ostream &os, const sc_int_bitref_r &a)
974{
975 a.print(os);
976 return os;
977}
978
979
980// ----------------------------------------------------------------------------
981// CLASS : sc_int_bitref
982//
983// Proxy class for sc_int bit selection (r-value and l-value).
984// ----------------------------------------------------------------------------
985
986// assignment operators
987
988inline sc_int_bitref &
989sc_int_bitref::operator = (const sc_int_bitref_r &b)
990{
991 m_obj_p->set(m_index, (bool)b);
992 m_obj_p->extend_sign();
993 return *this;
994}
995
996inline sc_int_bitref &
997sc_int_bitref::operator = (const sc_int_bitref &b)
998{
999 m_obj_p->set(m_index, (bool)b);
1000 m_obj_p->extend_sign();
1001 return *this;
1002}
1003
1004inline sc_int_bitref &
1005sc_int_bitref::operator = (bool b)
1006{
1007 m_obj_p->set(m_index, b);
1008 m_obj_p->extend_sign();
1009 return *this;
1010}
1011
1012
1013inline sc_int_bitref &
1014sc_int_bitref::operator &= (bool b)
1015{
1016 if (!b) {
1017 m_obj_p->set(m_index, b);
1018 m_obj_p->extend_sign();
1019 }
1020 return *this;
1021}
1022
1023inline sc_int_bitref &
1024sc_int_bitref::operator |= (bool b)
1025{
1026 if (b) {
1027 m_obj_p->set(m_index, b);
1028 m_obj_p->extend_sign();
1029 }
1030 return *this;
1031}
1032
1033inline sc_int_bitref &
1034sc_int_bitref::operator ^= (bool b)
1035{
1036 if (b) {
1037 m_obj_p->m_val ^= (UINT_ONE << m_index);
1038 m_obj_p->extend_sign();
1039 }
1040 return *this;
1041}
1042
1043
1044
1045inline ::std::istream &
1046operator >> (::std::istream &is, sc_int_bitref &a)
1047{
1048 a.scan(is);
1049 return is;
1050}
1051
1052
1053// ----------------------------------------------------------------------------
1054// CLASS : sc_int_subref_r
1055//
1056// Proxy class for sc_int part selection (r-value only).
1057// ----------------------------------------------------------------------------
1058
1059// implicit conversion to int_type
1060
1061inline sc_int_subref_r::operator uint_type() const
1062{
1063 uint_type /*int_type*/ val = m_obj_p->m_val;
1064 int uleft = SC_INTWIDTH - (m_left + 1);
1065 int uright = uleft + m_right;
1066 return (val << uleft >> uright);
1067}
1068
1069
1070// reduce methods
1071
1072inline bool
1073sc_int_subref_r::and_reduce() const
1074{
1075 sc_int_base a(*this);
1076 return a.and_reduce();
1077}
1078
1079inline bool
1080sc_int_subref_r::or_reduce() const
1081{
1082 sc_int_base a(*this);
1083 return a.or_reduce();
1084}
1085
1086inline bool
1087sc_int_subref_r::xor_reduce() const
1088{
1089 sc_int_base a(*this);
1090 return a.xor_reduce();
1091}
1092
1093
1094// explicit conversions
1095
1096inline int
1097sc_int_subref_r::to_int() const
1098{
1099 int result = static_cast<int>(operator uint_type());
1100 return result;
1101}
1102
1103inline unsigned int
1104sc_int_subref_r::to_uint() const
1105{
1106 unsigned int result = static_cast<unsigned int>(operator uint_type());
1107 return result;
1108}
1109
1110inline long
1111sc_int_subref_r::to_long() const
1112{
1113 long result = static_cast<long>(operator uint_type());
1114 return result;
1115}
1116
1117inline unsigned long
1118sc_int_subref_r::to_ulong() const
1119{
1120 unsigned long result = static_cast<unsigned long>(operator uint_type());
1121 return result;
1122}
1123
1124inline int64
1125sc_int_subref_r::to_int64() const
1126{
1127 int64 result = operator uint_type();
1128 return result;
1129}
1130
1131inline uint64
1132sc_int_subref_r::to_uint64() const
1133{
1134 uint64 result = operator uint_type();
1135 return result;
1136}
1137
1138inline double
1139sc_int_subref_r::to_double() const
1140{
1141 double result = static_cast<double>(operator uint_type());
1142 return result;
1143}
1144
1145
1146// explicit conversion to character string
1147
1148inline const std::string
1149sc_int_subref_r::to_string(sc_numrep numrep) const
1150{
1151 sc_uint_base a(length());
1152 a = operator uint_type();
1153 return a.to_string(numrep);
1154}
1155
1156inline const std::string
1157sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
1158{
1159 sc_uint_base a(length());
1160 a = operator uint_type();
1161 return a.to_string(numrep, w_prefix);
1162}
1163
1164
1165// functional notation for the reduce methods
1166
1167inline bool
1168and_reduce(const sc_int_subref_r &a)
1169{
1170 return a.and_reduce();
1171}
1172
1173inline bool
1174nand_reduce(const sc_int_subref_r &a)
1175{
1176 return a.nand_reduce();
1177}
1178
1179inline bool
1180or_reduce(const sc_int_subref_r &a)
1181{
1182 return a.or_reduce();
1183}
1184
1185inline bool
1186nor_reduce(const sc_int_subref_r &a)
1187{
1188 return a.nor_reduce();
1189}
1190
1191inline bool
1192xor_reduce(const sc_int_subref_r &a)
1193{
1194 return a.xor_reduce();
1195}
1196
1197inline bool
1198xnor_reduce(const sc_int_subref_r &a)
1199{
1200 return a.xnor_reduce();
1201}
1202
1203
1204
1205inline ::std::ostream &
1206operator << (::std::ostream &os, const sc_int_subref_r &a)
1207{
1208 a.print(os);
1209 return os;
1210}
1211
1212
1213// ----------------------------------------------------------------------------
1214// CLASS : sc_int_subref
1215//
1216// Proxy class for sc_int part selection (r-value and l-value).
1217// ----------------------------------------------------------------------------
1218
1219// assignment operators
1220
1221inline sc_int_subref &
1222sc_int_subref::operator = (const sc_int_base &a)
1223{
1224 return operator = (a.operator int_type());
1225}
1226
1227inline sc_int_subref &
1228sc_int_subref::operator = (const char *a)
1229{
1230 sc_int_base aa(length());
1231 return (*this = aa = a);
1232}
1233
1234
1235
1236inline ::std::istream &
1237operator >> (::std::istream &is, sc_int_subref &a)
1238{
1239 a.scan(is);
1240 return is;
1241}
1242
1243
1244// ----------------------------------------------------------------------------
1245// CLASS : sc_int_base
1246//
1247// Base class for sc_int.
1248// ----------------------------------------------------------------------------
1249
1250// bit selection
1251
1252inline sc_int_bitref &
1253sc_int_base::operator [] (int i)
1254{
1255 check_index(i);
1256 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1257 result_p->initialize(this, i);
1258 return *result_p;
1259}
1260
1261inline const sc_int_bitref_r &
1262sc_int_base::operator [] (int i) const
1263{
1264 check_index(i);
1265 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1266 result_p->initialize(this, i);
1267 return *result_p;
1268}
1269
1270
1271inline sc_int_bitref &
1272sc_int_base::bit(int i)
1273{
1274 check_index(i);
1275 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1276 result_p->initialize(this, i);
1277 return *result_p;
1278}
1279
1280inline const sc_int_bitref_r &
1281sc_int_base::bit(int i) const
1282{
1283 check_index(i);
1284 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1285 result_p->initialize(this, i);
1286 return *result_p;
1287}
1288
1289
1290// part selection
1291
1292inline sc_int_subref &
1293sc_int_base::operator () (int left, int right)
1294{
1295 check_range(left, right);
1296 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1297 result_p->initialize(this, left, right);
1298 return *result_p;
1299}
1300
1301inline const sc_int_subref_r &
1302sc_int_base::operator () (int left, int right) const
1303{
1304 check_range(left, right);
1305 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1306 result_p->initialize(this, left, right);
1307 return *result_p;
1308}
1309
1310
1311inline sc_int_subref &
1312sc_int_base::range(int left, int right)
1313{
1314 check_range(left, right);
1315 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1316 result_p->initialize(this, left, right);
1317 return *result_p;
1318}
1319
1320inline const sc_int_subref_r &
1321sc_int_base::range(int left, int right) const
1322{
1323 check_range(left, right);
1324 sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1325 result_p->initialize(this, left, right);
1326 return *result_p;
1327}
1328
1329
1330// functional notation for the reduce methods
1331
1332inline bool
1333and_reduce(const sc_int_base &a)
1334{
1335 return a.and_reduce();
1336}
1337
1338inline bool
1339nand_reduce(const sc_int_base &a)
1340{
1341 return a.nand_reduce();
1342}
1343
1344inline bool
1345or_reduce(const sc_int_base &a)
1346{
1347 return a.or_reduce();
1348}
1349
1350inline bool
1351nor_reduce(const sc_int_base &a)
1352{
1353 return a.nor_reduce();
1354}
1355
1356inline bool
1357xor_reduce(const sc_int_base &a)
1358{
1359 return a.xor_reduce();
1360}
1361
1362inline bool
1363xnor_reduce(const sc_int_base &a)
1364{
1365 return a.xnor_reduce();
1366}
1367
1368
1369
1370inline ::std::ostream &
1371operator << (::std::ostream &os, const sc_int_base &a)
1372{
1373 a.print(os);
1374 return os;
1375}
1376
1377inline ::std::istream &
1378operator >> (::std::istream &is, sc_int_base &a)
1379{
1380 a.scan(is);
1381 return is;
1382}
1383
1384} // namespace sc_dt
1385
1386#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__