sc_fxnum.hh (12853:e23d6f09069a) sc_fxnum.hh (13245:c666c5d4996b)
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_fxnum.h -
23
24 Original Author: Martin Janssen, Synopsys, Inc.
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// $Log: sc_fxnum.h,v $
39// Revision 1.5 2011/08/29 18:04:32 acg
40// Philipp A. Hartmann: miscellaneous clean ups.
41//
42// Revision 1.4 2011/08/24 22:05:43 acg
43// Torsten Maehne: initialization changes to remove warnings.
44//
45// Revision 1.3 2011/01/19 18:57:40 acg
46// Andy Goodrich: changes for IEEE_1666_2011.
47//
48// Revision 1.2 2009/03/09 17:26:46 acg
49// Andy Goodrich: removed ; from namespace { }
50//
51// Revision 1.1.1.1 2006/12/15 20:20:04 acg
52// SystemC 2.3
53//
54// Revision 1.3 2006/01/13 18:53:58 acg
55// Andy Goodrich: added $Log command so that CVS comments are reproduced in
56// the source.
57//
58
59#ifndef __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
60#define __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
61
62#include <iostream>
63
64#include "../bit/sc_lv_base.hh"
65#include "sc_fxnum_observer.hh"
66#include "sc_fxval.hh"
67#include "scfx_params.hh"
68
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_fxnum.h -
23
24 Original Author: Martin Janssen, Synopsys, Inc.
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// $Log: sc_fxnum.h,v $
39// Revision 1.5 2011/08/29 18:04:32 acg
40// Philipp A. Hartmann: miscellaneous clean ups.
41//
42// Revision 1.4 2011/08/24 22:05:43 acg
43// Torsten Maehne: initialization changes to remove warnings.
44//
45// Revision 1.3 2011/01/19 18:57:40 acg
46// Andy Goodrich: changes for IEEE_1666_2011.
47//
48// Revision 1.2 2009/03/09 17:26:46 acg
49// Andy Goodrich: removed ; from namespace { }
50//
51// Revision 1.1.1.1 2006/12/15 20:20:04 acg
52// SystemC 2.3
53//
54// Revision 1.3 2006/01/13 18:53:58 acg
55// Andy Goodrich: added $Log command so that CVS comments are reproduced in
56// the source.
57//
58
59#ifndef __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
60#define __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
61
62#include <iostream>
63
64#include "../bit/sc_lv_base.hh"
65#include "sc_fxnum_observer.hh"
66#include "sc_fxval.hh"
67#include "scfx_params.hh"
68
69namespace sc_core
69namespace sc_gem5
70{
71
70{
71
72class vcd_sc_fxnum_trace;
73class vcd_sc_fxnum_fast_trace;
74class wif_sc_fxnum_trace;
75class wif_sc_fxnum_fast_trace;
72template <typename T, typename B>
73class TraceValFxnumBase;
76
77} // namespace sc_core
78
79
80namespace sc_dt
81{
82
83// classes defined in this module
84class sc_fxnum_bitref;
85class sc_fxnum_fast_bitref;
86class sc_fxnum_subref;
87class sc_fxnum_fast_subref;
88class sc_fxnum;
89class sc_fxnum_fast;
90
91
92// ----------------------------------------------------------------------------
93// CLASS : sc_fxnum_bitref
94//
95// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
96// ----------------------------------------------------------------------------
97
98class sc_fxnum_bitref
99{
100 friend class sc_fxnum;
101 friend class sc_fxnum_fast_bitref;
102
103 bool get() const;
104 void set(bool);
105
106 // constructor
107 sc_fxnum_bitref(sc_fxnum &, int);
108
109 public:
110 // copy constructor
111 sc_fxnum_bitref(const sc_fxnum_bitref &);
112
113 // assignment operators
114#define DECL_ASN_OP_T(op, tp) \
115 sc_fxnum_bitref &operator op (tp);
116
117#define DECL_ASN_OP(op) \
118 DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
119 DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
120 DECL_ASN_OP_T(op, const sc_bit &) \
121 DECL_ASN_OP_T(op, bool)
122
123 DECL_ASN_OP(=)
124
125 DECL_ASN_OP(&=)
126 DECL_ASN_OP(|=)
127 DECL_ASN_OP(^=)
128
129#undef DECL_ASN_OP_T
130#undef DECL_ASN_OP
131
132 // implicit conversion
133 operator bool() const;
134
135 // print or dump content
136 void print(::std::ostream & =::std::cout) const;
137 void scan(::std::istream & =::std::cin);
138 void dump(::std::ostream & =::std::cout) const;
139
140 private:
141 sc_fxnum &m_num;
142 int m_idx;
143
144 private:
145 // disabled
146 sc_fxnum_bitref();
147};
148
149
150// ----------------------------------------------------------------------------
151// CLASS : sc_fxnum_fast_bitref
152//
153// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
154// ----------------------------------------------------------------------------
155
156class sc_fxnum_fast_bitref
157{
158 friend class sc_fxnum_fast;
159 friend class sc_fxnum_bitref;
160
161 bool get() const;
162 void set(bool);
163
164 // constructor
165 sc_fxnum_fast_bitref(sc_fxnum_fast &, int);
166
167 public:
168 // copy constructor
169 sc_fxnum_fast_bitref(const sc_fxnum_fast_bitref &);
170
171 // assignment operators
172#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast_bitref &operator op (tp);
173
174#define DECL_ASN_OP(op) \
175 DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
176 DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
177 DECL_ASN_OP_T(op, const sc_bit &) \
178 DECL_ASN_OP_T(op, bool)
179
180 DECL_ASN_OP(=)
181
182 DECL_ASN_OP(&=)
183 DECL_ASN_OP(|=)
184 DECL_ASN_OP(^=)
185
186#undef DECL_ASN_OP_T
187#undef DECL_ASN_OP
188
189 // implicit conversion
190 operator bool() const;
191
192 // print or dump content
193 void print(::std::ostream & =::std::cout) const;
194 void scan(::std::istream & =::std::cin);
195 void dump(::std::ostream & =::std::cout) const;
196
197 private:
198 sc_fxnum_fast &m_num;
199 int m_idx;
200
201 private:
202 // Disabled
203 sc_fxnum_fast_bitref();
204};
205
206
207// ----------------------------------------------------------------------------
208// CLASS : sc_fxnum_subref
209//
210// Proxy class for part-selection in class sc_fxnum,
211// behaves like sc_bv_base.
212// ----------------------------------------------------------------------------
213
214class sc_fxnum_subref
215{
216 friend class sc_fxnum;
217 friend class sc_fxnum_fast_subref;
218
219 bool get() const;
220 bool set();
221
222 // constructor
223 sc_fxnum_subref(sc_fxnum &, int, int);
224
225 public:
226 // copy constructor
227 sc_fxnum_subref(const sc_fxnum_subref &);
228
229 // destructor
230 ~sc_fxnum_subref();
231
232 // assignment operators
233#define DECL_ASN_OP_T(tp) \
234 sc_fxnum_subref &operator = (tp);
235
236 DECL_ASN_OP_T(const sc_fxnum_subref &)
237 DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
238 DECL_ASN_OP_T(const sc_bv_base &)
239 DECL_ASN_OP_T(const sc_lv_base &)
240 DECL_ASN_OP_T(const char *)
241 DECL_ASN_OP_T(const bool *)
242 DECL_ASN_OP_T(const sc_signed &)
243 DECL_ASN_OP_T(const sc_unsigned &)
244 DECL_ASN_OP_T(const sc_int_base &)
245 DECL_ASN_OP_T(const sc_uint_base &)
246 DECL_ASN_OP_T(int64)
247 DECL_ASN_OP_T(uint64)
248 DECL_ASN_OP_T(int)
249 DECL_ASN_OP_T(unsigned int)
250 DECL_ASN_OP_T(long)
251 DECL_ASN_OP_T(unsigned long)
252 DECL_ASN_OP_T(char)
253
254#undef DECL_ASN_OP_T
255
256#define DECL_ASN_OP_T_A(op, tp) \
257 sc_fxnum_subref &operator op ## = (tp);
258
259#define DECL_ASN_OP_A(op) \
260 DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
261 DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
262 DECL_ASN_OP_T_A(op, const sc_bv_base &) \
263 DECL_ASN_OP_T_A(op, const sc_lv_base &)
264
265 DECL_ASN_OP_A( &)
266 DECL_ASN_OP_A(|)
267 DECL_ASN_OP_A(^)
268
269#undef DECL_ASN_OP_T_A
270#undef DECL_ASN_OP_A
271
272 // relational operators
273#define DECL_REL_OP_T(op, tp) \
274 friend bool operator op (const sc_fxnum_subref &, tp); \
275 friend bool operator op (tp, const sc_fxnum_subref &);
276
277#define DECL_REL_OP(op) \
278 friend bool operator op (const sc_fxnum_subref &, \
279 const sc_fxnum_subref &); \
280 friend bool operator op (const sc_fxnum_subref &, \
281 const sc_fxnum_fast_subref &); \
282 DECL_REL_OP_T(op, const sc_bv_base &) \
283 DECL_REL_OP_T(op, const sc_lv_base &) \
284 DECL_REL_OP_T(op, const char *) \
285 DECL_REL_OP_T(op, const bool *) \
286 DECL_REL_OP_T(op, const sc_signed &) \
287 DECL_REL_OP_T(op, const sc_unsigned &) \
288 DECL_REL_OP_T(op, int) \
289 DECL_REL_OP_T(op, unsigned int) \
290 DECL_REL_OP_T(op, long) \
291 DECL_REL_OP_T(op, unsigned long)
292
293 DECL_REL_OP(==)
294 DECL_REL_OP(!=)
295
296#undef DECL_REL_OP_T
297#undef DECL_REL_OP
298
299 // reduce functions
300 bool and_reduce() const;
301 bool nand_reduce() const;
302 bool or_reduce() const;
303 bool nor_reduce() const;
304 bool xor_reduce() const;
305 bool xnor_reduce() const;
306
307 // query parameter
308 int length() const;
309
310 // explicit conversions
311 int to_int() const;
312 unsigned int to_uint() const;
313 long to_long() const;
314 unsigned long to_ulong() const;
315 int64 to_int64() const;
316 uint64 to_uint64() const;
317
318 const std::string to_string() const;
319 const std::string to_string(sc_numrep) const;
320 const std::string to_string(sc_numrep, bool) const;
321
322 // implicit conversion
323 operator sc_bv_base() const;
324
325 // print or dump content
326 void print(::std::ostream & =::std::cout) const;
327 void scan(::std::istream & =::std::cin);
328 void dump(::std::ostream & =::std::cout) const;
329
330 private:
331 sc_fxnum &m_num;
332 int m_from;
333 int m_to;
334
335 sc_bv_base &m_bv;
336
337 private:
338 // Disabled
339 sc_fxnum_subref();
340};
341
342
343// ----------------------------------------------------------------------------
344// CLASS : sc_fxnum_fast_subref
345//
346// Proxy class for part-selection in class sc_fxnum_fast,
347// behaves like sc_bv_base.
348// ----------------------------------------------------------------------------
349
350class sc_fxnum_fast_subref
351{
352 friend class sc_fxnum_fast;
353 friend class sc_fxnum_subref;
354
355 bool get() const;
356 bool set();
357
358 // constructor
359 sc_fxnum_fast_subref(sc_fxnum_fast &, int, int);
360
361 public:
362 // copy constructor
363 sc_fxnum_fast_subref(const sc_fxnum_fast_subref &);
364
365 // destructor
366 ~sc_fxnum_fast_subref();
367
368 // assignment operators
369#define DECL_ASN_OP_T(tp) \
370 sc_fxnum_fast_subref &operator = (tp);
371
372 DECL_ASN_OP_T(const sc_fxnum_subref &)
373 DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
374 DECL_ASN_OP_T(const sc_bv_base &)
375 DECL_ASN_OP_T(const sc_lv_base &)
376 DECL_ASN_OP_T(const char *)
377 DECL_ASN_OP_T(const bool *)
378 DECL_ASN_OP_T(const sc_signed &)
379 DECL_ASN_OP_T(const sc_unsigned &)
380 DECL_ASN_OP_T(const sc_int_base &)
381 DECL_ASN_OP_T(const sc_uint_base &)
382 DECL_ASN_OP_T(int64)
383 DECL_ASN_OP_T(uint64)
384 DECL_ASN_OP_T(int)
385 DECL_ASN_OP_T(unsigned int)
386 DECL_ASN_OP_T(long)
387 DECL_ASN_OP_T(unsigned long)
388 DECL_ASN_OP_T(char)
389
390#undef DECL_ASN_OP_T
391
392#define DECL_ASN_OP_T_A(op, tp) sc_fxnum_fast_subref &operator op ## = (tp);
393
394#define DECL_ASN_OP_A(op) \
395 DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
396 DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
397 DECL_ASN_OP_T_A(op, const sc_bv_base &) \
398 DECL_ASN_OP_T_A(op, const sc_lv_base &)
399
400 DECL_ASN_OP_A(&)
401 DECL_ASN_OP_A(|)
402 DECL_ASN_OP_A(^)
403
404#undef DECL_ASN_OP_T_A
405#undef DECL_ASN_OP_A
406
407 // relational operators
408#define DECL_REL_OP_T(op, tp) \
409 friend bool operator op (const sc_fxnum_fast_subref &, tp); \
410 friend bool operator op (tp, const sc_fxnum_fast_subref &);
411
412#define DECL_REL_OP(op) \
413 friend bool operator op (const sc_fxnum_fast_subref &, \
414 const sc_fxnum_fast_subref &); \
415 friend bool operator op (const sc_fxnum_fast_subref &, \
416 const sc_fxnum_subref &); \
417 DECL_REL_OP_T(op, const sc_bv_base &) \
418 DECL_REL_OP_T(op, const sc_lv_base &) \
419 DECL_REL_OP_T(op, const char *) \
420 DECL_REL_OP_T(op, const bool *) \
421 DECL_REL_OP_T(op, const sc_signed &) \
422 DECL_REL_OP_T(op, const sc_unsigned &) \
423 DECL_REL_OP_T(op, int) \
424 DECL_REL_OP_T(op, unsigned int) \
425 DECL_REL_OP_T(op, long) \
426 DECL_REL_OP_T(op, unsigned long)
427
428 DECL_REL_OP(==)
429 DECL_REL_OP(!=)
430
431#undef DECL_REL_OP_T
432#undef DECL_REL_OP
433
434 // reduce functions
435 bool and_reduce() const;
436 bool nand_reduce() const;
437 bool or_reduce() const;
438 bool nor_reduce() const;
439 bool xor_reduce() const;
440 bool xnor_reduce() const;
441
442 // query parameter
443 int length() const;
444
445 // explicit conversions
446 int to_int() const;
447 unsigned int to_uint() const;
448 long to_long() const;
449 unsigned long to_ulong() const;
450 int64 to_int64() const;
451 uint64 to_uint64() const;
452
453 const std::string to_string() const;
454 const std::string to_string(sc_numrep) const;
455 const std::string to_string(sc_numrep, bool) const;
456
457 // implicit conversion
458 operator sc_bv_base() const;
459
460 // print or dump content
461 void print(::std::ostream & =::std::cout) const;
462 void scan(::std::istream & =::std::cin);
463 void dump(::std::ostream & =::std::cout) const;
464
465 private:
466 sc_fxnum_fast &m_num;
467 int m_from;
468 int m_to;
469
470 sc_bv_base &m_bv;
471
472 private:
473 // Disabled
474 sc_fxnum_fast_subref();
475};
476
477
478// ----------------------------------------------------------------------------
479// CLASS : sc_fxnum
480//
481// Base class for the fixed-point types; arbitrary precision.
482// ----------------------------------------------------------------------------
483
484class sc_fxnum
485{
486 friend class sc_fxval;
487
488 friend class sc_fxnum_bitref;
489 friend class sc_fxnum_subref;
490 friend class sc_fxnum_fast_bitref;
491 friend class sc_fxnum_fast_subref;
492
74
75} // namespace sc_core
76
77
78namespace sc_dt
79{
80
81// classes defined in this module
82class sc_fxnum_bitref;
83class sc_fxnum_fast_bitref;
84class sc_fxnum_subref;
85class sc_fxnum_fast_subref;
86class sc_fxnum;
87class sc_fxnum_fast;
88
89
90// ----------------------------------------------------------------------------
91// CLASS : sc_fxnum_bitref
92//
93// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
94// ----------------------------------------------------------------------------
95
96class sc_fxnum_bitref
97{
98 friend class sc_fxnum;
99 friend class sc_fxnum_fast_bitref;
100
101 bool get() const;
102 void set(bool);
103
104 // constructor
105 sc_fxnum_bitref(sc_fxnum &, int);
106
107 public:
108 // copy constructor
109 sc_fxnum_bitref(const sc_fxnum_bitref &);
110
111 // assignment operators
112#define DECL_ASN_OP_T(op, tp) \
113 sc_fxnum_bitref &operator op (tp);
114
115#define DECL_ASN_OP(op) \
116 DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
117 DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
118 DECL_ASN_OP_T(op, const sc_bit &) \
119 DECL_ASN_OP_T(op, bool)
120
121 DECL_ASN_OP(=)
122
123 DECL_ASN_OP(&=)
124 DECL_ASN_OP(|=)
125 DECL_ASN_OP(^=)
126
127#undef DECL_ASN_OP_T
128#undef DECL_ASN_OP
129
130 // implicit conversion
131 operator bool() const;
132
133 // print or dump content
134 void print(::std::ostream & =::std::cout) const;
135 void scan(::std::istream & =::std::cin);
136 void dump(::std::ostream & =::std::cout) const;
137
138 private:
139 sc_fxnum &m_num;
140 int m_idx;
141
142 private:
143 // disabled
144 sc_fxnum_bitref();
145};
146
147
148// ----------------------------------------------------------------------------
149// CLASS : sc_fxnum_fast_bitref
150//
151// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
152// ----------------------------------------------------------------------------
153
154class sc_fxnum_fast_bitref
155{
156 friend class sc_fxnum_fast;
157 friend class sc_fxnum_bitref;
158
159 bool get() const;
160 void set(bool);
161
162 // constructor
163 sc_fxnum_fast_bitref(sc_fxnum_fast &, int);
164
165 public:
166 // copy constructor
167 sc_fxnum_fast_bitref(const sc_fxnum_fast_bitref &);
168
169 // assignment operators
170#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast_bitref &operator op (tp);
171
172#define DECL_ASN_OP(op) \
173 DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
174 DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
175 DECL_ASN_OP_T(op, const sc_bit &) \
176 DECL_ASN_OP_T(op, bool)
177
178 DECL_ASN_OP(=)
179
180 DECL_ASN_OP(&=)
181 DECL_ASN_OP(|=)
182 DECL_ASN_OP(^=)
183
184#undef DECL_ASN_OP_T
185#undef DECL_ASN_OP
186
187 // implicit conversion
188 operator bool() const;
189
190 // print or dump content
191 void print(::std::ostream & =::std::cout) const;
192 void scan(::std::istream & =::std::cin);
193 void dump(::std::ostream & =::std::cout) const;
194
195 private:
196 sc_fxnum_fast &m_num;
197 int m_idx;
198
199 private:
200 // Disabled
201 sc_fxnum_fast_bitref();
202};
203
204
205// ----------------------------------------------------------------------------
206// CLASS : sc_fxnum_subref
207//
208// Proxy class for part-selection in class sc_fxnum,
209// behaves like sc_bv_base.
210// ----------------------------------------------------------------------------
211
212class sc_fxnum_subref
213{
214 friend class sc_fxnum;
215 friend class sc_fxnum_fast_subref;
216
217 bool get() const;
218 bool set();
219
220 // constructor
221 sc_fxnum_subref(sc_fxnum &, int, int);
222
223 public:
224 // copy constructor
225 sc_fxnum_subref(const sc_fxnum_subref &);
226
227 // destructor
228 ~sc_fxnum_subref();
229
230 // assignment operators
231#define DECL_ASN_OP_T(tp) \
232 sc_fxnum_subref &operator = (tp);
233
234 DECL_ASN_OP_T(const sc_fxnum_subref &)
235 DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
236 DECL_ASN_OP_T(const sc_bv_base &)
237 DECL_ASN_OP_T(const sc_lv_base &)
238 DECL_ASN_OP_T(const char *)
239 DECL_ASN_OP_T(const bool *)
240 DECL_ASN_OP_T(const sc_signed &)
241 DECL_ASN_OP_T(const sc_unsigned &)
242 DECL_ASN_OP_T(const sc_int_base &)
243 DECL_ASN_OP_T(const sc_uint_base &)
244 DECL_ASN_OP_T(int64)
245 DECL_ASN_OP_T(uint64)
246 DECL_ASN_OP_T(int)
247 DECL_ASN_OP_T(unsigned int)
248 DECL_ASN_OP_T(long)
249 DECL_ASN_OP_T(unsigned long)
250 DECL_ASN_OP_T(char)
251
252#undef DECL_ASN_OP_T
253
254#define DECL_ASN_OP_T_A(op, tp) \
255 sc_fxnum_subref &operator op ## = (tp);
256
257#define DECL_ASN_OP_A(op) \
258 DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
259 DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
260 DECL_ASN_OP_T_A(op, const sc_bv_base &) \
261 DECL_ASN_OP_T_A(op, const sc_lv_base &)
262
263 DECL_ASN_OP_A( &)
264 DECL_ASN_OP_A(|)
265 DECL_ASN_OP_A(^)
266
267#undef DECL_ASN_OP_T_A
268#undef DECL_ASN_OP_A
269
270 // relational operators
271#define DECL_REL_OP_T(op, tp) \
272 friend bool operator op (const sc_fxnum_subref &, tp); \
273 friend bool operator op (tp, const sc_fxnum_subref &);
274
275#define DECL_REL_OP(op) \
276 friend bool operator op (const sc_fxnum_subref &, \
277 const sc_fxnum_subref &); \
278 friend bool operator op (const sc_fxnum_subref &, \
279 const sc_fxnum_fast_subref &); \
280 DECL_REL_OP_T(op, const sc_bv_base &) \
281 DECL_REL_OP_T(op, const sc_lv_base &) \
282 DECL_REL_OP_T(op, const char *) \
283 DECL_REL_OP_T(op, const bool *) \
284 DECL_REL_OP_T(op, const sc_signed &) \
285 DECL_REL_OP_T(op, const sc_unsigned &) \
286 DECL_REL_OP_T(op, int) \
287 DECL_REL_OP_T(op, unsigned int) \
288 DECL_REL_OP_T(op, long) \
289 DECL_REL_OP_T(op, unsigned long)
290
291 DECL_REL_OP(==)
292 DECL_REL_OP(!=)
293
294#undef DECL_REL_OP_T
295#undef DECL_REL_OP
296
297 // reduce functions
298 bool and_reduce() const;
299 bool nand_reduce() const;
300 bool or_reduce() const;
301 bool nor_reduce() const;
302 bool xor_reduce() const;
303 bool xnor_reduce() const;
304
305 // query parameter
306 int length() const;
307
308 // explicit conversions
309 int to_int() const;
310 unsigned int to_uint() const;
311 long to_long() const;
312 unsigned long to_ulong() const;
313 int64 to_int64() const;
314 uint64 to_uint64() const;
315
316 const std::string to_string() const;
317 const std::string to_string(sc_numrep) const;
318 const std::string to_string(sc_numrep, bool) const;
319
320 // implicit conversion
321 operator sc_bv_base() const;
322
323 // print or dump content
324 void print(::std::ostream & =::std::cout) const;
325 void scan(::std::istream & =::std::cin);
326 void dump(::std::ostream & =::std::cout) const;
327
328 private:
329 sc_fxnum &m_num;
330 int m_from;
331 int m_to;
332
333 sc_bv_base &m_bv;
334
335 private:
336 // Disabled
337 sc_fxnum_subref();
338};
339
340
341// ----------------------------------------------------------------------------
342// CLASS : sc_fxnum_fast_subref
343//
344// Proxy class for part-selection in class sc_fxnum_fast,
345// behaves like sc_bv_base.
346// ----------------------------------------------------------------------------
347
348class sc_fxnum_fast_subref
349{
350 friend class sc_fxnum_fast;
351 friend class sc_fxnum_subref;
352
353 bool get() const;
354 bool set();
355
356 // constructor
357 sc_fxnum_fast_subref(sc_fxnum_fast &, int, int);
358
359 public:
360 // copy constructor
361 sc_fxnum_fast_subref(const sc_fxnum_fast_subref &);
362
363 // destructor
364 ~sc_fxnum_fast_subref();
365
366 // assignment operators
367#define DECL_ASN_OP_T(tp) \
368 sc_fxnum_fast_subref &operator = (tp);
369
370 DECL_ASN_OP_T(const sc_fxnum_subref &)
371 DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
372 DECL_ASN_OP_T(const sc_bv_base &)
373 DECL_ASN_OP_T(const sc_lv_base &)
374 DECL_ASN_OP_T(const char *)
375 DECL_ASN_OP_T(const bool *)
376 DECL_ASN_OP_T(const sc_signed &)
377 DECL_ASN_OP_T(const sc_unsigned &)
378 DECL_ASN_OP_T(const sc_int_base &)
379 DECL_ASN_OP_T(const sc_uint_base &)
380 DECL_ASN_OP_T(int64)
381 DECL_ASN_OP_T(uint64)
382 DECL_ASN_OP_T(int)
383 DECL_ASN_OP_T(unsigned int)
384 DECL_ASN_OP_T(long)
385 DECL_ASN_OP_T(unsigned long)
386 DECL_ASN_OP_T(char)
387
388#undef DECL_ASN_OP_T
389
390#define DECL_ASN_OP_T_A(op, tp) sc_fxnum_fast_subref &operator op ## = (tp);
391
392#define DECL_ASN_OP_A(op) \
393 DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
394 DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
395 DECL_ASN_OP_T_A(op, const sc_bv_base &) \
396 DECL_ASN_OP_T_A(op, const sc_lv_base &)
397
398 DECL_ASN_OP_A(&)
399 DECL_ASN_OP_A(|)
400 DECL_ASN_OP_A(^)
401
402#undef DECL_ASN_OP_T_A
403#undef DECL_ASN_OP_A
404
405 // relational operators
406#define DECL_REL_OP_T(op, tp) \
407 friend bool operator op (const sc_fxnum_fast_subref &, tp); \
408 friend bool operator op (tp, const sc_fxnum_fast_subref &);
409
410#define DECL_REL_OP(op) \
411 friend bool operator op (const sc_fxnum_fast_subref &, \
412 const sc_fxnum_fast_subref &); \
413 friend bool operator op (const sc_fxnum_fast_subref &, \
414 const sc_fxnum_subref &); \
415 DECL_REL_OP_T(op, const sc_bv_base &) \
416 DECL_REL_OP_T(op, const sc_lv_base &) \
417 DECL_REL_OP_T(op, const char *) \
418 DECL_REL_OP_T(op, const bool *) \
419 DECL_REL_OP_T(op, const sc_signed &) \
420 DECL_REL_OP_T(op, const sc_unsigned &) \
421 DECL_REL_OP_T(op, int) \
422 DECL_REL_OP_T(op, unsigned int) \
423 DECL_REL_OP_T(op, long) \
424 DECL_REL_OP_T(op, unsigned long)
425
426 DECL_REL_OP(==)
427 DECL_REL_OP(!=)
428
429#undef DECL_REL_OP_T
430#undef DECL_REL_OP
431
432 // reduce functions
433 bool and_reduce() const;
434 bool nand_reduce() const;
435 bool or_reduce() const;
436 bool nor_reduce() const;
437 bool xor_reduce() const;
438 bool xnor_reduce() const;
439
440 // query parameter
441 int length() const;
442
443 // explicit conversions
444 int to_int() const;
445 unsigned int to_uint() const;
446 long to_long() const;
447 unsigned long to_ulong() const;
448 int64 to_int64() const;
449 uint64 to_uint64() const;
450
451 const std::string to_string() const;
452 const std::string to_string(sc_numrep) const;
453 const std::string to_string(sc_numrep, bool) const;
454
455 // implicit conversion
456 operator sc_bv_base() const;
457
458 // print or dump content
459 void print(::std::ostream & =::std::cout) const;
460 void scan(::std::istream & =::std::cin);
461 void dump(::std::ostream & =::std::cout) const;
462
463 private:
464 sc_fxnum_fast &m_num;
465 int m_from;
466 int m_to;
467
468 sc_bv_base &m_bv;
469
470 private:
471 // Disabled
472 sc_fxnum_fast_subref();
473};
474
475
476// ----------------------------------------------------------------------------
477// CLASS : sc_fxnum
478//
479// Base class for the fixed-point types; arbitrary precision.
480// ----------------------------------------------------------------------------
481
482class sc_fxnum
483{
484 friend class sc_fxval;
485
486 friend class sc_fxnum_bitref;
487 friend class sc_fxnum_subref;
488 friend class sc_fxnum_fast_bitref;
489 friend class sc_fxnum_fast_subref;
490
493 friend class sc_core::vcd_sc_fxnum_trace;
494 friend class sc_core::wif_sc_fxnum_trace;
491 template <typename T, typename B>
492 friend class sc_gem5::TraceValFxnumBase;
495
496 protected:
497 sc_fxnum_observer *observer() const;
498
499 void cast();
500
501 // constructors
502 sc_fxnum(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
503 sc_fxnum_observer *);
504
505#define DECL_CTOR_T(tp) \
506 sc_fxnum(tp, const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &, \
507 sc_fxnum_observer *);
508
509 DECL_CTOR_T(int)
510 DECL_CTOR_T(unsigned int)
511 DECL_CTOR_T(long)
512 DECL_CTOR_T(unsigned long)
513 DECL_CTOR_T(float)
514 DECL_CTOR_T(double)
515 DECL_CTOR_T(const char *)
516 DECL_CTOR_T(const sc_fxval &)
517 DECL_CTOR_T(const sc_fxval_fast &)
518 DECL_CTOR_T(const sc_fxnum &)
519 DECL_CTOR_T(const sc_fxnum_fast &)
520
521 DECL_CTOR_T(int64)
522 DECL_CTOR_T(uint64)
523 DECL_CTOR_T(const sc_int_base &)
524 DECL_CTOR_T(const sc_uint_base &)
525 DECL_CTOR_T(const sc_signed &)
526 DECL_CTOR_T(const sc_unsigned &)
527
528#undef DECL_CTOR_T
529
530 ~sc_fxnum();
531
532 // internal use only;
533 const scfx_rep *get_rep() const;
534
535 public:
536 // unary operators
537 const sc_fxval operator - () const;
538 const sc_fxval operator + () const;
539
540 // unary functions
541 friend void neg(sc_fxval &, const sc_fxnum &);
542 friend void neg(sc_fxnum &, const sc_fxnum &);
543
544 // binary operators
545#define DECL_BIN_OP_T(op, tp) \
546 friend const sc_fxval operator op (const sc_fxnum &, tp); \
547 friend const sc_fxval operator op (tp, const sc_fxnum &);
548
549#define DECL_BIN_OP_OTHER(op) \
550 DECL_BIN_OP_T(op, int64) \
551 DECL_BIN_OP_T(op, uint64) \
552 DECL_BIN_OP_T(op, const sc_int_base &) \
553 DECL_BIN_OP_T(op, const sc_uint_base &) \
554 DECL_BIN_OP_T(op, const sc_signed &) \
555 DECL_BIN_OP_T(op, const sc_unsigned &)
556
557#define DECL_BIN_OP(op, dummy) \
558 friend const sc_fxval operator op (const sc_fxnum &, const sc_fxnum &); \
559 DECL_BIN_OP_T(op, int) \
560 DECL_BIN_OP_T(op, unsigned int) \
561 DECL_BIN_OP_T(op, long) \
562 DECL_BIN_OP_T(op, unsigned long) \
563 DECL_BIN_OP_T(op, float) \
564 DECL_BIN_OP_T(op, double) \
565 DECL_BIN_OP_T(op, const char *) \
566 DECL_BIN_OP_T(op, const sc_fxval &) \
567 DECL_BIN_OP_T(op, const sc_fxval_fast &) \
568 DECL_BIN_OP_T(op, const sc_fxnum_fast &) \
569 DECL_BIN_OP_OTHER(op)
570
571 DECL_BIN_OP(*, mult)
572 DECL_BIN_OP(+, add)
573 DECL_BIN_OP(-, sub)
574// don't use macros
575// DECL_BIN_OP(/, div)
576 friend const sc_fxval operator / (const sc_fxnum &, const sc_fxnum &);
577 DECL_BIN_OP_T(/, int)
578 DECL_BIN_OP_T(/, unsigned int)
579 DECL_BIN_OP_T(/, long)
580 DECL_BIN_OP_T(/, unsigned long)
581 DECL_BIN_OP_T(/, float)
582 DECL_BIN_OP_T(/, double)
583 DECL_BIN_OP_T(/, const char *)
584 DECL_BIN_OP_T(/, const sc_fxval &)
585 DECL_BIN_OP_T(/, const sc_fxval_fast &)
586 DECL_BIN_OP_T(/, const sc_fxnum_fast &)
587// DECL_BIN_OP_OTHER(op)
588
589 DECL_BIN_OP_T(/, int64)
590 DECL_BIN_OP_T(/, uint64)
591 DECL_BIN_OP_T(/, const sc_int_base &)
592 DECL_BIN_OP_T(/, const sc_uint_base &)
593 DECL_BIN_OP_T(/, const sc_signed &)
594 DECL_BIN_OP_T(/, const sc_unsigned &)
595
596#undef DECL_BIN_OP_T
597#undef DECL_BIN_OP_OTHER
598#undef DECL_BIN_OP
599
600 friend const sc_fxval operator << (const sc_fxnum &, int);
601 friend const sc_fxval operator >> (const sc_fxnum &, int);
602
603 // binary functions
604#define DECL_BIN_FNC_T(fnc, tp) \
605 friend void fnc (sc_fxval &, const sc_fxnum &, tp); \
606 friend void fnc (sc_fxval &, tp, const sc_fxnum &); \
607 friend void fnc (sc_fxnum &, const sc_fxnum &, tp); \
608 friend void fnc (sc_fxnum &, tp, const sc_fxnum &);
609
610#define DECL_BIN_FNC_OTHER(fnc) \
611 DECL_BIN_FNC_T(fnc, int64) \
612 DECL_BIN_FNC_T(fnc, uint64) \
613 DECL_BIN_FNC_T(fnc, const sc_int_base &) \
614 DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
615 DECL_BIN_FNC_T(fnc, const sc_signed &) \
616 DECL_BIN_FNC_T(fnc, const sc_unsigned &)
617
618#define DECL_BIN_FNC(fnc) \
619 friend void fnc (sc_fxval &, const sc_fxnum &, const sc_fxnum &); \
620 friend void fnc (sc_fxnum &, const sc_fxnum &, const sc_fxnum &); \
621 DECL_BIN_FNC_T(fnc, int) \
622 DECL_BIN_FNC_T(fnc, unsigned int) \
623 DECL_BIN_FNC_T(fnc, long) \
624 DECL_BIN_FNC_T(fnc, unsigned long) \
625 DECL_BIN_FNC_T(fnc, float) \
626 DECL_BIN_FNC_T(fnc, double) \
627 DECL_BIN_FNC_T(fnc, const char *) \
628 DECL_BIN_FNC_T(fnc, const sc_fxval &) \
629 DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
630 DECL_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
631 DECL_BIN_FNC_OTHER(fnc)
632
633 DECL_BIN_FNC(mult)
634 DECL_BIN_FNC(div)
635 DECL_BIN_FNC(add)
636 DECL_BIN_FNC(sub)
637
638#undef DECL_BIN_FNC_T
639#undef DECL_BIN_FNC_OTHER
640#undef DECL_BIN_FNC
641
642 friend void lshift(sc_fxval &, const sc_fxnum &, int);
643 friend void rshift(sc_fxval &, const sc_fxnum &, int);
644 friend void lshift(sc_fxnum &, const sc_fxnum &, int);
645 friend void rshift(sc_fxnum &, const sc_fxnum &, int);
646
647 // relational (including equality) operators
648#define DECL_REL_OP_T(op, tp) \
649 friend bool operator op (const sc_fxnum &, tp); \
650 friend bool operator op (tp, const sc_fxnum &);
651
652#define DECL_REL_OP_OTHER(op) \
653 DECL_REL_OP_T(op, int64) \
654 DECL_REL_OP_T(op, uint64) \
655 DECL_REL_OP_T(op, const sc_int_base &) \
656 DECL_REL_OP_T(op, const sc_uint_base &) \
657 DECL_REL_OP_T(op, const sc_signed &) \
658 DECL_REL_OP_T(op, const sc_unsigned &)
659
660#define DECL_REL_OP(op) \
661 friend bool operator op (const sc_fxnum &, const sc_fxnum &); \
662 DECL_REL_OP_T(op, int) \
663 DECL_REL_OP_T(op, unsigned int) \
664 DECL_REL_OP_T(op, long) \
665 DECL_REL_OP_T(op, unsigned long) \
666 DECL_REL_OP_T(op, float) \
667 DECL_REL_OP_T(op, double) \
668 DECL_REL_OP_T(op, const char *) \
669 DECL_REL_OP_T(op, const sc_fxval &) \
670 DECL_REL_OP_T(op, const sc_fxval_fast &) \
671 DECL_REL_OP_T(op, const sc_fxnum_fast &) \
672 DECL_REL_OP_OTHER(op)
673
674 DECL_REL_OP(<)
675 DECL_REL_OP(<=)
676 DECL_REL_OP(>)
677 DECL_REL_OP(>=)
678 DECL_REL_OP(==)
679 DECL_REL_OP(!=)
680
681#undef DECL_REL_OP_T
682#undef DECL_REL_OP_OTHER
683#undef DECL_REL_OP
684
685 // assignment operators
686#define DECL_ASN_OP_T(op, tp) \
687 sc_fxnum &operator op(tp);
688
689#define DECL_ASN_OP_OTHER(op) \
690 DECL_ASN_OP_T(op, int64) \
691 DECL_ASN_OP_T(op, uint64) \
692 DECL_ASN_OP_T(op, const sc_int_base &) \
693 DECL_ASN_OP_T(op, const sc_uint_base &) \
694 DECL_ASN_OP_T(op, const sc_signed &) \
695 DECL_ASN_OP_T(op, const sc_unsigned &)
696
697#define DECL_ASN_OP(op) \
698 DECL_ASN_OP_T(op, int) \
699 DECL_ASN_OP_T(op, unsigned int) \
700 DECL_ASN_OP_T(op, long) \
701 DECL_ASN_OP_T(op, unsigned long) \
702 DECL_ASN_OP_T(op, float) \
703 DECL_ASN_OP_T(op, double) \
704 DECL_ASN_OP_T(op, const char *) \
705 DECL_ASN_OP_T(op, const sc_fxval &) \
706 DECL_ASN_OP_T(op, const sc_fxval_fast &) \
707 DECL_ASN_OP_T(op, const sc_fxnum &) \
708 DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
709 DECL_ASN_OP_OTHER(op)
710
711 DECL_ASN_OP(=)
712
713 DECL_ASN_OP(*=)
714 DECL_ASN_OP(/=)
715 DECL_ASN_OP(+=)
716 DECL_ASN_OP(-=)
717
718 DECL_ASN_OP_T(<<=, int)
719 DECL_ASN_OP_T(>>=, int)
720
721#undef DECL_ASN_OP_T
722#undef DECL_ASN_OP_OTHER
723#undef DECL_ASN_OP
724
725 // auto-increment and auto-decrement
726 const sc_fxval operator ++ (int);
727 const sc_fxval operator -- (int);
728
729 sc_fxnum &operator ++ ();
730 sc_fxnum &operator -- ();
731
732 // bit selection
733 const sc_fxnum_bitref operator [] (int) const;
734 sc_fxnum_bitref operator [] (int);
735
736 const sc_fxnum_bitref bit(int) const;
737 sc_fxnum_bitref bit(int);
738
739 // part selection
740 const sc_fxnum_subref operator () (int, int) const;
741 sc_fxnum_subref operator () (int, int);
742
743 const sc_fxnum_subref range(int, int) const;
744 sc_fxnum_subref range(int, int);
745
746 const sc_fxnum_subref operator () () const;
747 sc_fxnum_subref operator () ();
748
749 const sc_fxnum_subref range() const;
750 sc_fxnum_subref range();
751
752 // implicit conversion
753 operator double() const; // necessary evil!
754
755 // explicit conversion to primitive types
756 short to_short() const;
757 unsigned short to_ushort() const;
758 int to_int() const;
759 unsigned int to_uint() const;
760 long to_long() const;
761 unsigned long to_ulong() const;
762 int64 to_int64() const;
763 uint64 to_uint64() const;
764 float to_float() const;
765 double to_double() const;
766
767 // explicit conversion to character string
768 const std::string to_string() const;
769 const std::string to_string(sc_numrep) const;
770 const std::string to_string(sc_numrep, bool) const;
771 const std::string to_string(sc_fmt) const;
772 const std::string to_string(sc_numrep, sc_fmt) const;
773 const std::string to_string(sc_numrep, bool, sc_fmt) const;
774
775 const std::string to_dec() const;
776 const std::string to_bin() const;
777 const std::string to_oct() const;
778 const std::string to_hex() const;
779
780 // query value
781 bool is_neg() const;
782 bool is_zero() const;
783
784 // internal use only;
785 bool is_normal() const;
786
787 bool quantization_flag() const;
788 bool overflow_flag() const;
789
790 const sc_fxval value() const;
791
792 // query parameters
793 int wl() const;
794 int iwl() const;
795 sc_q_mode q_mode() const;
796 sc_o_mode o_mode() const;
797 int n_bits() const;
798
799 const sc_fxtype_params &type_params() const;
800
801 const sc_fxcast_switch &cast_switch() const;
802
803 // print or dump content
804 void print(::std::ostream & =::std::cout) const;
805 void scan(::std::istream & =::std::cin);
806 void dump(::std::ostream & =::std::cout) const;
807
808 // internal use only;
809 void observer_read() const;
810
811 // internal use only;
812 bool get_bit(int) const;
813
814 protected:
815 bool set_bit(int, bool);
816
817 bool get_slice(int, int, sc_bv_base &) const;
818 bool set_slice(int, int, const sc_bv_base &);
819
820 sc_fxnum_observer *lock_observer() const;
821 void unlock_observer(sc_fxnum_observer *) const;
822
823 private:
824 scfx_rep *m_rep;
825
826 scfx_params m_params;
827 bool m_q_flag;
828 bool m_o_flag;
829
830 mutable sc_fxnum_observer *m_observer;
831
832 private:
833 // disabled
834 sc_fxnum();
835 sc_fxnum(const sc_fxnum &);
836};
837
838
839// ----------------------------------------------------------------------------
840// CLASS : sc_fxnum_fast
841//
842// Base class for the fixed-point types; limited precision.
843// ----------------------------------------------------------------------------
844
845class sc_fxnum_fast
846{
847 friend class sc_fxval_fast;
848
849 friend class sc_fxnum_bitref;
850 friend class sc_fxnum_subref;
851 friend class sc_fxnum_fast_bitref;
852 friend class sc_fxnum_fast_subref;
853
493
494 protected:
495 sc_fxnum_observer *observer() const;
496
497 void cast();
498
499 // constructors
500 sc_fxnum(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
501 sc_fxnum_observer *);
502
503#define DECL_CTOR_T(tp) \
504 sc_fxnum(tp, const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &, \
505 sc_fxnum_observer *);
506
507 DECL_CTOR_T(int)
508 DECL_CTOR_T(unsigned int)
509 DECL_CTOR_T(long)
510 DECL_CTOR_T(unsigned long)
511 DECL_CTOR_T(float)
512 DECL_CTOR_T(double)
513 DECL_CTOR_T(const char *)
514 DECL_CTOR_T(const sc_fxval &)
515 DECL_CTOR_T(const sc_fxval_fast &)
516 DECL_CTOR_T(const sc_fxnum &)
517 DECL_CTOR_T(const sc_fxnum_fast &)
518
519 DECL_CTOR_T(int64)
520 DECL_CTOR_T(uint64)
521 DECL_CTOR_T(const sc_int_base &)
522 DECL_CTOR_T(const sc_uint_base &)
523 DECL_CTOR_T(const sc_signed &)
524 DECL_CTOR_T(const sc_unsigned &)
525
526#undef DECL_CTOR_T
527
528 ~sc_fxnum();
529
530 // internal use only;
531 const scfx_rep *get_rep() const;
532
533 public:
534 // unary operators
535 const sc_fxval operator - () const;
536 const sc_fxval operator + () const;
537
538 // unary functions
539 friend void neg(sc_fxval &, const sc_fxnum &);
540 friend void neg(sc_fxnum &, const sc_fxnum &);
541
542 // binary operators
543#define DECL_BIN_OP_T(op, tp) \
544 friend const sc_fxval operator op (const sc_fxnum &, tp); \
545 friend const sc_fxval operator op (tp, const sc_fxnum &);
546
547#define DECL_BIN_OP_OTHER(op) \
548 DECL_BIN_OP_T(op, int64) \
549 DECL_BIN_OP_T(op, uint64) \
550 DECL_BIN_OP_T(op, const sc_int_base &) \
551 DECL_BIN_OP_T(op, const sc_uint_base &) \
552 DECL_BIN_OP_T(op, const sc_signed &) \
553 DECL_BIN_OP_T(op, const sc_unsigned &)
554
555#define DECL_BIN_OP(op, dummy) \
556 friend const sc_fxval operator op (const sc_fxnum &, const sc_fxnum &); \
557 DECL_BIN_OP_T(op, int) \
558 DECL_BIN_OP_T(op, unsigned int) \
559 DECL_BIN_OP_T(op, long) \
560 DECL_BIN_OP_T(op, unsigned long) \
561 DECL_BIN_OP_T(op, float) \
562 DECL_BIN_OP_T(op, double) \
563 DECL_BIN_OP_T(op, const char *) \
564 DECL_BIN_OP_T(op, const sc_fxval &) \
565 DECL_BIN_OP_T(op, const sc_fxval_fast &) \
566 DECL_BIN_OP_T(op, const sc_fxnum_fast &) \
567 DECL_BIN_OP_OTHER(op)
568
569 DECL_BIN_OP(*, mult)
570 DECL_BIN_OP(+, add)
571 DECL_BIN_OP(-, sub)
572// don't use macros
573// DECL_BIN_OP(/, div)
574 friend const sc_fxval operator / (const sc_fxnum &, const sc_fxnum &);
575 DECL_BIN_OP_T(/, int)
576 DECL_BIN_OP_T(/, unsigned int)
577 DECL_BIN_OP_T(/, long)
578 DECL_BIN_OP_T(/, unsigned long)
579 DECL_BIN_OP_T(/, float)
580 DECL_BIN_OP_T(/, double)
581 DECL_BIN_OP_T(/, const char *)
582 DECL_BIN_OP_T(/, const sc_fxval &)
583 DECL_BIN_OP_T(/, const sc_fxval_fast &)
584 DECL_BIN_OP_T(/, const sc_fxnum_fast &)
585// DECL_BIN_OP_OTHER(op)
586
587 DECL_BIN_OP_T(/, int64)
588 DECL_BIN_OP_T(/, uint64)
589 DECL_BIN_OP_T(/, const sc_int_base &)
590 DECL_BIN_OP_T(/, const sc_uint_base &)
591 DECL_BIN_OP_T(/, const sc_signed &)
592 DECL_BIN_OP_T(/, const sc_unsigned &)
593
594#undef DECL_BIN_OP_T
595#undef DECL_BIN_OP_OTHER
596#undef DECL_BIN_OP
597
598 friend const sc_fxval operator << (const sc_fxnum &, int);
599 friend const sc_fxval operator >> (const sc_fxnum &, int);
600
601 // binary functions
602#define DECL_BIN_FNC_T(fnc, tp) \
603 friend void fnc (sc_fxval &, const sc_fxnum &, tp); \
604 friend void fnc (sc_fxval &, tp, const sc_fxnum &); \
605 friend void fnc (sc_fxnum &, const sc_fxnum &, tp); \
606 friend void fnc (sc_fxnum &, tp, const sc_fxnum &);
607
608#define DECL_BIN_FNC_OTHER(fnc) \
609 DECL_BIN_FNC_T(fnc, int64) \
610 DECL_BIN_FNC_T(fnc, uint64) \
611 DECL_BIN_FNC_T(fnc, const sc_int_base &) \
612 DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
613 DECL_BIN_FNC_T(fnc, const sc_signed &) \
614 DECL_BIN_FNC_T(fnc, const sc_unsigned &)
615
616#define DECL_BIN_FNC(fnc) \
617 friend void fnc (sc_fxval &, const sc_fxnum &, const sc_fxnum &); \
618 friend void fnc (sc_fxnum &, const sc_fxnum &, const sc_fxnum &); \
619 DECL_BIN_FNC_T(fnc, int) \
620 DECL_BIN_FNC_T(fnc, unsigned int) \
621 DECL_BIN_FNC_T(fnc, long) \
622 DECL_BIN_FNC_T(fnc, unsigned long) \
623 DECL_BIN_FNC_T(fnc, float) \
624 DECL_BIN_FNC_T(fnc, double) \
625 DECL_BIN_FNC_T(fnc, const char *) \
626 DECL_BIN_FNC_T(fnc, const sc_fxval &) \
627 DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
628 DECL_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
629 DECL_BIN_FNC_OTHER(fnc)
630
631 DECL_BIN_FNC(mult)
632 DECL_BIN_FNC(div)
633 DECL_BIN_FNC(add)
634 DECL_BIN_FNC(sub)
635
636#undef DECL_BIN_FNC_T
637#undef DECL_BIN_FNC_OTHER
638#undef DECL_BIN_FNC
639
640 friend void lshift(sc_fxval &, const sc_fxnum &, int);
641 friend void rshift(sc_fxval &, const sc_fxnum &, int);
642 friend void lshift(sc_fxnum &, const sc_fxnum &, int);
643 friend void rshift(sc_fxnum &, const sc_fxnum &, int);
644
645 // relational (including equality) operators
646#define DECL_REL_OP_T(op, tp) \
647 friend bool operator op (const sc_fxnum &, tp); \
648 friend bool operator op (tp, const sc_fxnum &);
649
650#define DECL_REL_OP_OTHER(op) \
651 DECL_REL_OP_T(op, int64) \
652 DECL_REL_OP_T(op, uint64) \
653 DECL_REL_OP_T(op, const sc_int_base &) \
654 DECL_REL_OP_T(op, const sc_uint_base &) \
655 DECL_REL_OP_T(op, const sc_signed &) \
656 DECL_REL_OP_T(op, const sc_unsigned &)
657
658#define DECL_REL_OP(op) \
659 friend bool operator op (const sc_fxnum &, const sc_fxnum &); \
660 DECL_REL_OP_T(op, int) \
661 DECL_REL_OP_T(op, unsigned int) \
662 DECL_REL_OP_T(op, long) \
663 DECL_REL_OP_T(op, unsigned long) \
664 DECL_REL_OP_T(op, float) \
665 DECL_REL_OP_T(op, double) \
666 DECL_REL_OP_T(op, const char *) \
667 DECL_REL_OP_T(op, const sc_fxval &) \
668 DECL_REL_OP_T(op, const sc_fxval_fast &) \
669 DECL_REL_OP_T(op, const sc_fxnum_fast &) \
670 DECL_REL_OP_OTHER(op)
671
672 DECL_REL_OP(<)
673 DECL_REL_OP(<=)
674 DECL_REL_OP(>)
675 DECL_REL_OP(>=)
676 DECL_REL_OP(==)
677 DECL_REL_OP(!=)
678
679#undef DECL_REL_OP_T
680#undef DECL_REL_OP_OTHER
681#undef DECL_REL_OP
682
683 // assignment operators
684#define DECL_ASN_OP_T(op, tp) \
685 sc_fxnum &operator op(tp);
686
687#define DECL_ASN_OP_OTHER(op) \
688 DECL_ASN_OP_T(op, int64) \
689 DECL_ASN_OP_T(op, uint64) \
690 DECL_ASN_OP_T(op, const sc_int_base &) \
691 DECL_ASN_OP_T(op, const sc_uint_base &) \
692 DECL_ASN_OP_T(op, const sc_signed &) \
693 DECL_ASN_OP_T(op, const sc_unsigned &)
694
695#define DECL_ASN_OP(op) \
696 DECL_ASN_OP_T(op, int) \
697 DECL_ASN_OP_T(op, unsigned int) \
698 DECL_ASN_OP_T(op, long) \
699 DECL_ASN_OP_T(op, unsigned long) \
700 DECL_ASN_OP_T(op, float) \
701 DECL_ASN_OP_T(op, double) \
702 DECL_ASN_OP_T(op, const char *) \
703 DECL_ASN_OP_T(op, const sc_fxval &) \
704 DECL_ASN_OP_T(op, const sc_fxval_fast &) \
705 DECL_ASN_OP_T(op, const sc_fxnum &) \
706 DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
707 DECL_ASN_OP_OTHER(op)
708
709 DECL_ASN_OP(=)
710
711 DECL_ASN_OP(*=)
712 DECL_ASN_OP(/=)
713 DECL_ASN_OP(+=)
714 DECL_ASN_OP(-=)
715
716 DECL_ASN_OP_T(<<=, int)
717 DECL_ASN_OP_T(>>=, int)
718
719#undef DECL_ASN_OP_T
720#undef DECL_ASN_OP_OTHER
721#undef DECL_ASN_OP
722
723 // auto-increment and auto-decrement
724 const sc_fxval operator ++ (int);
725 const sc_fxval operator -- (int);
726
727 sc_fxnum &operator ++ ();
728 sc_fxnum &operator -- ();
729
730 // bit selection
731 const sc_fxnum_bitref operator [] (int) const;
732 sc_fxnum_bitref operator [] (int);
733
734 const sc_fxnum_bitref bit(int) const;
735 sc_fxnum_bitref bit(int);
736
737 // part selection
738 const sc_fxnum_subref operator () (int, int) const;
739 sc_fxnum_subref operator () (int, int);
740
741 const sc_fxnum_subref range(int, int) const;
742 sc_fxnum_subref range(int, int);
743
744 const sc_fxnum_subref operator () () const;
745 sc_fxnum_subref operator () ();
746
747 const sc_fxnum_subref range() const;
748 sc_fxnum_subref range();
749
750 // implicit conversion
751 operator double() const; // necessary evil!
752
753 // explicit conversion to primitive types
754 short to_short() const;
755 unsigned short to_ushort() const;
756 int to_int() const;
757 unsigned int to_uint() const;
758 long to_long() const;
759 unsigned long to_ulong() const;
760 int64 to_int64() const;
761 uint64 to_uint64() const;
762 float to_float() const;
763 double to_double() const;
764
765 // explicit conversion to character string
766 const std::string to_string() const;
767 const std::string to_string(sc_numrep) const;
768 const std::string to_string(sc_numrep, bool) const;
769 const std::string to_string(sc_fmt) const;
770 const std::string to_string(sc_numrep, sc_fmt) const;
771 const std::string to_string(sc_numrep, bool, sc_fmt) const;
772
773 const std::string to_dec() const;
774 const std::string to_bin() const;
775 const std::string to_oct() const;
776 const std::string to_hex() const;
777
778 // query value
779 bool is_neg() const;
780 bool is_zero() const;
781
782 // internal use only;
783 bool is_normal() const;
784
785 bool quantization_flag() const;
786 bool overflow_flag() const;
787
788 const sc_fxval value() const;
789
790 // query parameters
791 int wl() const;
792 int iwl() const;
793 sc_q_mode q_mode() const;
794 sc_o_mode o_mode() const;
795 int n_bits() const;
796
797 const sc_fxtype_params &type_params() const;
798
799 const sc_fxcast_switch &cast_switch() const;
800
801 // print or dump content
802 void print(::std::ostream & =::std::cout) const;
803 void scan(::std::istream & =::std::cin);
804 void dump(::std::ostream & =::std::cout) const;
805
806 // internal use only;
807 void observer_read() const;
808
809 // internal use only;
810 bool get_bit(int) const;
811
812 protected:
813 bool set_bit(int, bool);
814
815 bool get_slice(int, int, sc_bv_base &) const;
816 bool set_slice(int, int, const sc_bv_base &);
817
818 sc_fxnum_observer *lock_observer() const;
819 void unlock_observer(sc_fxnum_observer *) const;
820
821 private:
822 scfx_rep *m_rep;
823
824 scfx_params m_params;
825 bool m_q_flag;
826 bool m_o_flag;
827
828 mutable sc_fxnum_observer *m_observer;
829
830 private:
831 // disabled
832 sc_fxnum();
833 sc_fxnum(const sc_fxnum &);
834};
835
836
837// ----------------------------------------------------------------------------
838// CLASS : sc_fxnum_fast
839//
840// Base class for the fixed-point types; limited precision.
841// ----------------------------------------------------------------------------
842
843class sc_fxnum_fast
844{
845 friend class sc_fxval_fast;
846
847 friend class sc_fxnum_bitref;
848 friend class sc_fxnum_subref;
849 friend class sc_fxnum_fast_bitref;
850 friend class sc_fxnum_fast_subref;
851
854 friend class sc_core::vcd_sc_fxnum_fast_trace;
855 friend class sc_core::wif_sc_fxnum_fast_trace;
852 template <typename T, typename B>
853 friend class sc_gem5::TraceValFxnumBase;
856
857 protected:
858 sc_fxnum_fast_observer *observer() const;
859
860 void cast();
861
862 // constructors
863 sc_fxnum_fast(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
864 sc_fxnum_fast_observer *);
865
866#define DECL_CTOR_T(tp) \
867 sc_fxnum_fast(tp, const sc_fxtype_params &, sc_enc, \
868 const sc_fxcast_switch &, sc_fxnum_fast_observer *);
869
870 DECL_CTOR_T(int)
871 DECL_CTOR_T(unsigned int)
872 DECL_CTOR_T(long)
873 DECL_CTOR_T(unsigned long)
874 DECL_CTOR_T(float)
875 DECL_CTOR_T(double)
876 DECL_CTOR_T(const char *)
877 DECL_CTOR_T(const sc_fxval &)
878 DECL_CTOR_T(const sc_fxval_fast &)
879 DECL_CTOR_T(const sc_fxnum &)
880 DECL_CTOR_T(const sc_fxnum_fast &)
881
882 DECL_CTOR_T(int64)
883 DECL_CTOR_T(uint64)
884 DECL_CTOR_T(const sc_int_base &)
885 DECL_CTOR_T(const sc_uint_base &)
886 DECL_CTOR_T(const sc_signed &)
887 DECL_CTOR_T(const sc_unsigned &)
888
889#undef DECL_CTOR_T
890 ~sc_fxnum_fast();
891
892 // internal use only;
893 double get_val() const;
894
895 public:
896 // unary operators
897 const sc_fxval_fast operator - () const;
898 const sc_fxval_fast operator + () const;
899
900 // unary functions
901 friend void neg(sc_fxval_fast &, const sc_fxnum_fast &);
902 friend void neg(sc_fxnum_fast &, const sc_fxnum_fast &);
903
904
905 // binary operators
906#define DECL_BIN_OP_T(op, tp) \
907 friend const sc_fxval_fast operator op (const sc_fxnum_fast &, tp); \
908 friend const sc_fxval_fast operator op (tp, const sc_fxnum_fast &);
909
910#define DECL_BIN_OP_OTHER(op) \
911 DECL_BIN_OP_T(op, int64) \
912 DECL_BIN_OP_T(op, uint64) \
913 DECL_BIN_OP_T(op, const sc_int_base &) \
914 DECL_BIN_OP_T(op, const sc_uint_base &) \
915 DECL_BIN_OP_T(op, const sc_signed &) \
916 DECL_BIN_OP_T(op, const sc_unsigned &)
917
918#define DECL_BIN_OP(op, dummy) \
919 friend const sc_fxval_fast operator op (const sc_fxnum_fast &, \
920 const sc_fxnum_fast &); \
921 DECL_BIN_OP_T(op, int) \
922 DECL_BIN_OP_T(op, unsigned int) \
923 DECL_BIN_OP_T(op, long) \
924 DECL_BIN_OP_T(op, unsigned long) \
925 DECL_BIN_OP_T(op, float) \
926 DECL_BIN_OP_T(op, double) \
927 DECL_BIN_OP_T(op, const char *) \
928 DECL_BIN_OP_T(op, const sc_fxval_fast &) \
929 DECL_BIN_OP_OTHER(op)
930
931 DECL_BIN_OP(*, mult)
932 DECL_BIN_OP(+, add)
933 DECL_BIN_OP(-, sub)
934// DECL_BIN_OP(/, div)
935 friend const sc_fxval_fast operator / (const sc_fxnum_fast &,
936 const sc_fxnum_fast &);
937 DECL_BIN_OP_T(/, int)
938 DECL_BIN_OP_T(/, unsigned int)
939 DECL_BIN_OP_T(/, long)
940 DECL_BIN_OP_T(/, unsigned long)
941 DECL_BIN_OP_T(/, float)
942 DECL_BIN_OP_T(/, double)
943 DECL_BIN_OP_T(/, const char *)
944 DECL_BIN_OP_T(/, const sc_fxval_fast &)
945// DECL_BIN_OP_OTHER(op)
946
947 DECL_BIN_OP_T(/, int64) \
948 DECL_BIN_OP_T(/, uint64) \
949 DECL_BIN_OP_T(/, const sc_int_base &) \
950 DECL_BIN_OP_T(/, const sc_uint_base &) \
951 DECL_BIN_OP_T(/, const sc_signed &) \
952 DECL_BIN_OP_T(/, const sc_unsigned &)
953
954#undef DECL_BIN_OP_T
955#undef DECL_BIN_OP_OTHER
956#undef DECL_BIN_OP
957
958 friend const sc_fxval_fast operator << (const sc_fxnum_fast &, int);
959 friend const sc_fxval_fast operator >> (const sc_fxnum_fast &, int);
960
961 // binary functions
962#define DECL_BIN_FNC_T(fnc, tp) \
963 friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, tp); \
964 friend void fnc (sc_fxval_fast &, tp, const sc_fxnum_fast &); \
965 friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, tp); \
966 friend void fnc (sc_fxnum_fast &, tp, const sc_fxnum_fast &);
967
968#define DECL_BIN_FNC_OTHER(fnc) \
969 DECL_BIN_FNC_T(fnc, int64) \
970 DECL_BIN_FNC_T(fnc, uint64) \
971 DECL_BIN_FNC_T(fnc, const sc_int_base &) \
972 DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
973 DECL_BIN_FNC_T(fnc, const sc_signed &) \
974 DECL_BIN_FNC_T(fnc, const sc_unsigned &)
975
976#define DECL_BIN_FNC(fnc) \
977 friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, \
978 const sc_fxnum_fast &); \
979 friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, \
980 const sc_fxnum_fast &); \
981 DECL_BIN_FNC_T(fnc, int) \
982 DECL_BIN_FNC_T(fnc, unsigned int) \
983 DECL_BIN_FNC_T(fnc, long) \
984 DECL_BIN_FNC_T(fnc, unsigned long) \
985 DECL_BIN_FNC_T(fnc, float) \
986 DECL_BIN_FNC_T(fnc, double) \
987 DECL_BIN_FNC_T(fnc, const char *) \
988 DECL_BIN_FNC_T(fnc, const sc_fxval &) \
989 DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
990 DECL_BIN_FNC_T(fnc, const sc_fxnum &) \
991 DECL_BIN_FNC_OTHER(fnc)
992
993 DECL_BIN_FNC(mult)
994 DECL_BIN_FNC(div)
995 DECL_BIN_FNC(add)
996 DECL_BIN_FNC(sub)
997
998#undef DECL_BIN_FNC_T
999#undef DECL_BIN_FNC_OTHER
1000#undef DECL_BIN_FNC
1001
1002 friend void lshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1003 friend void rshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1004 friend void lshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1005 friend void rshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1006
1007 // relational (including equality) operators
1008#define DECL_REL_OP_T(op, tp) \
1009 friend bool operator op (const sc_fxnum_fast &, tp); \
1010 friend bool operator op (tp, const sc_fxnum_fast &);
1011
1012#define DECL_REL_OP_OTHER(op) \
1013 DECL_REL_OP_T(op, int64) \
1014 DECL_REL_OP_T(op, uint64) \
1015 DECL_REL_OP_T(op, const sc_int_base &) \
1016 DECL_REL_OP_T(op, const sc_uint_base &) \
1017 DECL_REL_OP_T(op, const sc_signed &) \
1018 DECL_REL_OP_T(op, const sc_unsigned &)
1019
1020#define DECL_REL_OP(op) \
1021 friend bool operator op (const sc_fxnum_fast &, const sc_fxnum_fast &); \
1022 DECL_REL_OP_T(op, int) \
1023 DECL_REL_OP_T(op, unsigned int) \
1024 DECL_REL_OP_T(op, long) \
1025 DECL_REL_OP_T(op, unsigned long) \
1026 DECL_REL_OP_T(op, float) \
1027 DECL_REL_OP_T(op, double) \
1028 DECL_REL_OP_T(op, const char *) \
1029 DECL_REL_OP_T(op, const sc_fxval_fast &) \
1030 DECL_REL_OP_OTHER(op)
1031
1032 DECL_REL_OP(<)
1033 DECL_REL_OP(<=)
1034 DECL_REL_OP(>)
1035 DECL_REL_OP(>=)
1036 DECL_REL_OP(==)
1037 DECL_REL_OP(!=)
1038
1039#undef DECL_REL_OP_T
1040#undef DECL_REL_OP_OTHER
1041#undef DECL_REL_OP
1042
1043 // assignment operators
1044#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast &operator op(tp);
1045
1046#define DECL_ASN_OP_OTHER(op) \
1047 DECL_ASN_OP_T(op, int64) \
1048 DECL_ASN_OP_T(op, uint64) \
1049 DECL_ASN_OP_T(op, const sc_int_base &) \
1050 DECL_ASN_OP_T(op, const sc_uint_base &) \
1051 DECL_ASN_OP_T(op, const sc_signed &) \
1052 DECL_ASN_OP_T(op, const sc_unsigned &)
1053
1054#define DECL_ASN_OP(op) \
1055 DECL_ASN_OP_T(op, int) \
1056 DECL_ASN_OP_T(op, unsigned int) \
1057 DECL_ASN_OP_T(op, long) \
1058 DECL_ASN_OP_T(op, unsigned long) \
1059 DECL_ASN_OP_T(op, float) \
1060 DECL_ASN_OP_T(op, double) \
1061 DECL_ASN_OP_T(op, const char *) \
1062 DECL_ASN_OP_T(op, const sc_fxval &) \
1063 DECL_ASN_OP_T(op, const sc_fxval_fast &) \
1064 DECL_ASN_OP_T(op, const sc_fxnum &) \
1065 DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
1066 DECL_ASN_OP_OTHER(op)
1067
1068 DECL_ASN_OP(=)
1069
1070 DECL_ASN_OP(*=)
1071 DECL_ASN_OP(/=)
1072 DECL_ASN_OP(+=)
1073 DECL_ASN_OP(-=)
1074
1075 DECL_ASN_OP_T(<<=, int)
1076 DECL_ASN_OP_T(>>=, int)
1077
1078#undef DECL_ASN_OP_T
1079#undef DECL_ASN_OP_OTHER
1080#undef DECL_ASN_OP
1081
1082 // auto-increment and auto-decrement
1083 const sc_fxval_fast operator ++ (int);
1084 const sc_fxval_fast operator -- (int);
1085
1086 sc_fxnum_fast &operator ++ ();
1087 sc_fxnum_fast &operator -- ();
1088
1089 // bit selection
1090 const sc_fxnum_fast_bitref operator [] (int) const;
1091 sc_fxnum_fast_bitref operator [] (int);
1092
1093 const sc_fxnum_fast_bitref bit(int) const;
1094 sc_fxnum_fast_bitref bit(int);
1095
1096 // part selection
1097 const sc_fxnum_fast_subref operator () (int, int) const;
1098 sc_fxnum_fast_subref operator () (int, int);
1099
1100 const sc_fxnum_fast_subref range(int, int) const;
1101 sc_fxnum_fast_subref range(int, int);
1102
1103
1104 const sc_fxnum_fast_subref operator () () const;
1105 sc_fxnum_fast_subref operator () ();
1106
1107 const sc_fxnum_fast_subref range() const;
1108 sc_fxnum_fast_subref range();
1109
1110 // implicit conversion
1111 operator double() const; // necessary evil!
1112
1113 // explicit conversion to primitive types
1114 short to_short() const;
1115 unsigned short to_ushort() const;
1116 int to_int() const;
1117 unsigned int to_uint() const;
1118 long to_long() const;
1119 unsigned long to_ulong() const;
1120 int64 to_int64() const;
1121 uint64 to_uint64() const;
1122 float to_float() const;
1123 double to_double() const;
1124
1125 // explicit conversion to character string
1126 const std::string to_string() const;
1127 const std::string to_string(sc_numrep) const;
1128 const std::string to_string(sc_numrep, bool) const;
1129 const std::string to_string(sc_fmt) const;
1130 const std::string to_string(sc_numrep, sc_fmt) const;
1131 const std::string to_string(sc_numrep, bool, sc_fmt) const;
1132
1133 const std::string to_dec() const;
1134 const std::string to_bin() const;
1135 const std::string to_oct() const;
1136 const std::string to_hex() const;
1137
1138 // query value
1139 bool is_neg() const;
1140 bool is_zero() const;
1141
1142 // internal use only;
1143 bool is_normal() const;
1144
1145 bool quantization_flag() const;
1146 bool overflow_flag() const;
1147
1148 const sc_fxval_fast value() const;
1149
1150 // query parameters
1151 int wl() const;
1152 int iwl() const;
1153 sc_q_mode q_mode() const;
1154 sc_o_mode o_mode() const;
1155 int n_bits() const;
1156
1157 const sc_fxtype_params &type_params() const;
1158
1159 const sc_fxcast_switch &cast_switch() const;
1160
1161 // print or dump content
1162 void print(::std::ostream & =::std::cout) const;
1163 void scan(::std::istream & =::std::cin);
1164 void dump(::std::ostream & =::std::cout) const;
1165
1166 // internal use only;
1167 void observer_read() const;
1168
1169 // internal use only;
1170 bool get_bit(int) const;
1171
1172 protected:
1173 bool set_bit(int, bool);
1174
1175 bool get_slice(int, int, sc_bv_base &) const;
1176 bool set_slice(int, int, const sc_bv_base &);
1177
1178 sc_fxnum_fast_observer *lock_observer() const;
1179 void unlock_observer(sc_fxnum_fast_observer *) const;
1180
1181 private:
1182 double m_val;
1183
1184 scfx_params m_params;
1185 bool m_q_flag;
1186 bool m_o_flag;
1187
1188 mutable sc_fxnum_fast_observer *m_observer;
1189
1190 private:
1191 // Disabled
1192 sc_fxnum_fast();
1193 sc_fxnum_fast(const sc_fxnum_fast &);
1194};
1195
1196
1197// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1198
1199// ----------------------------------------------------------------------------
1200// CLASS : sc_fxnum_bitref
1201//
1202// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
1203// ----------------------------------------------------------------------------
1204
1205// constructor
1206
1207inline
1208sc_fxnum_bitref::sc_fxnum_bitref(sc_fxnum &num_, int idx_) :
1209 m_num(num_), m_idx(idx_)
1210{}
1211
1212// copy constructor
1213inline sc_fxnum_bitref::sc_fxnum_bitref(const sc_fxnum_bitref &a) :
1214 m_num(a.m_num), m_idx(a.m_idx)
1215{}
1216
1217// assignment operators
1218inline sc_fxnum_bitref &
1219sc_fxnum_bitref::operator = (const sc_fxnum_bitref &a)
1220{
1221 if (&a != this) {
1222 SC_FXNUM_OBSERVER_READ_(a.m_num)
1223 set(a.get());
1224 SC_FXNUM_OBSERVER_WRITE_(m_num)
1225 }
1226 return *this;
1227}
1228
1229inline sc_fxnum_bitref &
1230sc_fxnum_bitref::operator = (const sc_fxnum_fast_bitref &a)
1231{
1232 SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1233 set(a.get());
1234 SC_FXNUM_OBSERVER_WRITE_(m_num)
1235 return *this;
1236}
1237
1238inline sc_fxnum_bitref &
1239sc_fxnum_bitref::operator = (const sc_bit &a)
1240{
1241 set(static_cast<bool>(a));
1242 SC_FXNUM_OBSERVER_WRITE_(m_num)
1243 return *this;
1244}
1245
1246inline sc_fxnum_bitref &
1247sc_fxnum_bitref::operator = (bool a)
1248{
1249 set(a);
1250 SC_FXNUM_OBSERVER_WRITE_(m_num)
1251 return *this;
1252}
1253
1254inline sc_fxnum_bitref &
1255sc_fxnum_bitref::operator &= (const sc_fxnum_bitref &b)
1256{
1257 SC_FXNUM_OBSERVER_READ_(m_num)
1258 SC_FXNUM_OBSERVER_READ_(b.m_num)
1259 set(get() && b.get());
1260 SC_FXNUM_OBSERVER_WRITE_(m_num)
1261 return *this;
1262}
1263
1264inline sc_fxnum_bitref &
1265sc_fxnum_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1266{
1267 SC_FXNUM_OBSERVER_READ_(m_num)
1268 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1269 set(get() && b.get());
1270 SC_FXNUM_OBSERVER_WRITE_(m_num)
1271 return *this;
1272}
1273
1274inline sc_fxnum_bitref &
1275sc_fxnum_bitref::operator &= (const sc_bit &b)
1276{
1277 SC_FXNUM_OBSERVER_READ_(m_num)
1278 set(get() && static_cast<bool>(b));
1279 SC_FXNUM_OBSERVER_WRITE_(m_num)
1280 return *this;
1281}
1282
1283inline sc_fxnum_bitref &
1284sc_fxnum_bitref::operator &= (bool b)
1285{
1286 SC_FXNUM_OBSERVER_READ_(m_num)
1287 set(get() && b);
1288 SC_FXNUM_OBSERVER_WRITE_(m_num)
1289 return *this;
1290}
1291
1292
1293inline sc_fxnum_bitref &
1294sc_fxnum_bitref::operator |= (const sc_fxnum_bitref &b)
1295{
1296 SC_FXNUM_OBSERVER_READ_(m_num)
1297 SC_FXNUM_OBSERVER_READ_(b.m_num)
1298 set(get() || b.get());
1299 SC_FXNUM_OBSERVER_WRITE_(m_num)
1300 return *this;
1301}
1302
1303inline sc_fxnum_bitref &
1304sc_fxnum_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1305{
1306 SC_FXNUM_OBSERVER_READ_(m_num)
1307 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1308 set(get() || b.get());
1309 SC_FXNUM_OBSERVER_WRITE_(m_num)
1310 return *this;
1311}
1312
1313inline sc_fxnum_bitref &
1314sc_fxnum_bitref::operator |= (const sc_bit &b)
1315{
1316 SC_FXNUM_OBSERVER_READ_(m_num)
1317 set(get() || static_cast<bool>(b));
1318 SC_FXNUM_OBSERVER_WRITE_(m_num)
1319 return *this;
1320}
1321
1322inline sc_fxnum_bitref &
1323sc_fxnum_bitref::operator |= (bool b)
1324{
1325 SC_FXNUM_OBSERVER_READ_(m_num)
1326 set(get() || b);
1327 SC_FXNUM_OBSERVER_WRITE_(m_num)
1328 return *this;
1329}
1330
1331
1332inline sc_fxnum_bitref &
1333sc_fxnum_bitref::operator ^= (const sc_fxnum_bitref &b)
1334{
1335 SC_FXNUM_OBSERVER_READ_(m_num)
1336 SC_FXNUM_OBSERVER_READ_(b.m_num)
1337 set(get() != b.get());
1338 SC_FXNUM_OBSERVER_WRITE_(m_num)
1339 return *this;
1340}
1341
1342inline sc_fxnum_bitref &
1343sc_fxnum_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1344{
1345 SC_FXNUM_OBSERVER_READ_(m_num)
1346 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1347 set(get() != b.get());
1348 SC_FXNUM_OBSERVER_WRITE_(m_num)
1349 return *this;
1350}
1351
1352inline sc_fxnum_bitref &
1353sc_fxnum_bitref::operator ^= (const sc_bit &b)
1354{
1355 SC_FXNUM_OBSERVER_READ_(m_num)
1356 set(get() != static_cast<bool>(b));
1357 SC_FXNUM_OBSERVER_WRITE_(m_num)
1358 return *this;
1359}
1360
1361inline sc_fxnum_bitref &
1362sc_fxnum_bitref::operator ^= (bool b)
1363{
1364 SC_FXNUM_OBSERVER_READ_(m_num)
1365 set(get() != b);
1366 SC_FXNUM_OBSERVER_WRITE_(m_num)
1367 return *this;
1368}
1369
1370// implicit conversion
1371inline sc_fxnum_bitref::operator bool() const
1372{
1373 SC_FXNUM_OBSERVER_READ_(m_num)
1374 return get();
1375}
1376
1377inline ::std::ostream &
1378operator << (::std::ostream &os, const sc_fxnum_bitref &a)
1379{
1380 a.print(os);
1381 return os;
1382}
1383
1384inline ::std::istream &
1385operator >> (::std::istream &is, sc_fxnum_bitref &a)
1386{
1387 a.scan(is);
1388 return is;
1389}
1390
1391
1392// ----------------------------------------------------------------------------
1393// CLASS : sc_fxnum_fast_bitref
1394//
1395// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
1396// ----------------------------------------------------------------------------
1397
1398// constructor
1399inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1400 sc_fxnum_fast &num_, int idx_) : m_num(num_), m_idx(idx_)
1401{}
1402
1403// copy constructor
1404inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1405 const sc_fxnum_fast_bitref &a) : m_num(a.m_num), m_idx(a.m_idx)
1406{}
1407
1408// assignment operators
1409inline sc_fxnum_fast_bitref &
1410sc_fxnum_fast_bitref::operator = (const sc_fxnum_bitref &a)
1411{
1412 SC_FXNUM_OBSERVER_READ_(a.m_num)
1413 set(a.get());
1414 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1415 return *this;
1416}
1417
1418inline sc_fxnum_fast_bitref &
1419sc_fxnum_fast_bitref::operator = (const sc_fxnum_fast_bitref &a)
1420{
1421 if (&a != this) {
1422 SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1423 set(a.get());
1424 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1425 }
1426 return *this;
1427}
1428
1429inline sc_fxnum_fast_bitref &
1430sc_fxnum_fast_bitref::operator = (const sc_bit &a)
1431{
1432 set(static_cast<bool>(a));
1433 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1434 return *this;
1435}
1436
1437inline sc_fxnum_fast_bitref &
1438sc_fxnum_fast_bitref::operator = (bool a)
1439{
1440 set(a);
1441 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1442 return *this;
1443}
1444
1445
1446inline sc_fxnum_fast_bitref &
1447sc_fxnum_fast_bitref::operator &= (const sc_fxnum_bitref &b)
1448{
1449 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1450 SC_FXNUM_OBSERVER_READ_(b.m_num)
1451 set(get() && b.get());
1452 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1453 return *this;
1454}
1455
1456inline sc_fxnum_fast_bitref &
1457sc_fxnum_fast_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1458{
1459 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1460 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1461 set(get() && b.get());
1462 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1463 return *this;
1464}
1465
1466inline sc_fxnum_fast_bitref &
1467sc_fxnum_fast_bitref::operator &= (const sc_bit &b)
1468{
1469 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1470 set(get() && static_cast<bool>(b));
1471 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1472 return *this;
1473}
1474
1475inline sc_fxnum_fast_bitref &
1476sc_fxnum_fast_bitref::operator &= (bool b)
1477{
1478 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1479 set(get() && b);
1480 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1481 return *this;
1482}
1483
1484
1485inline sc_fxnum_fast_bitref &
1486sc_fxnum_fast_bitref::operator |= (const sc_fxnum_bitref &b)
1487{
1488 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1489 SC_FXNUM_OBSERVER_READ_(b.m_num)
1490 set(get() || b.get());
1491 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1492 return *this;
1493}
1494
1495inline sc_fxnum_fast_bitref &
1496sc_fxnum_fast_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1497{
1498 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1499 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1500 set(get() || b.get());
1501 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1502 return *this;
1503}
1504
1505inline sc_fxnum_fast_bitref &
1506sc_fxnum_fast_bitref::operator |= (const sc_bit &b)
1507{
1508 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1509 set(get() || static_cast<bool>(b));
1510 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1511 return *this;
1512}
1513
1514inline sc_fxnum_fast_bitref &
1515sc_fxnum_fast_bitref::operator |= (bool b)
1516{
1517 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1518 set(get() || b);
1519 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1520 return *this;
1521}
1522
1523
1524inline sc_fxnum_fast_bitref &
1525sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_bitref &b)
1526{
1527 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1528 SC_FXNUM_OBSERVER_READ_(b.m_num)
1529 set(get() != b.get());
1530 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1531 return *this;
1532}
1533
1534inline sc_fxnum_fast_bitref &
1535sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1536{
1537 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1538 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1539 set(get() != b.get());
1540 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1541 return *this;
1542}
1543
1544inline sc_fxnum_fast_bitref &
1545sc_fxnum_fast_bitref::operator ^= (const sc_bit &b)
1546{
1547 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1548 set(get() != static_cast<bool>(b));
1549 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1550 return *this;
1551}
1552
1553inline sc_fxnum_fast_bitref &
1554sc_fxnum_fast_bitref::operator ^= (bool b)
1555{
1556 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1557 set(get() != b);
1558 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1559 return *this;
1560}
1561
1562
1563// implicit conversion
1564inline sc_fxnum_fast_bitref::operator bool() const
1565{
1566 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1567 return get();
1568}
1569
1570inline ::std::ostream &
1571operator << (::std::ostream &os, const sc_fxnum_fast_bitref &a)
1572{
1573 a.print(os);
1574 return os;
1575}
1576
1577inline ::std::istream &
1578operator >> (::std::istream &is, sc_fxnum_fast_bitref &a)
1579{
1580 a.scan(is);
1581 return is;
1582}
1583
1584
1585// ----------------------------------------------------------------------------
1586// CLASS : sc_fxnum_subref
1587//
1588// Proxy class for part-selection in class sc_fxnum,
1589// behaves like sc_bv_base.
1590// ----------------------------------------------------------------------------
1591
1592// constructor
1593inline sc_fxnum_subref::sc_fxnum_subref(sc_fxnum &num_, int from_, int to_) :
1594 m_num(num_), m_from(from_), m_to(to_),
1595 m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1596{}
1597
1598// copy constructor
1599inline sc_fxnum_subref::sc_fxnum_subref(const sc_fxnum_subref &a) :
1600 m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1601 m_bv(*new sc_bv_base(a.m_bv))
1602{}
1603
1604// destructor
1605inline sc_fxnum_subref::~sc_fxnum_subref()
1606{
1607 delete &m_bv;
1608}
1609
1610// assignment operators
1611inline sc_fxnum_subref &
1612sc_fxnum_subref::operator = (const sc_fxnum_subref &a)
1613{
1614 if (&a != this) {
1615 m_bv = static_cast<sc_bv_base>(a);
1616 set();
1617 SC_FXNUM_OBSERVER_WRITE_(m_num)
1618 }
1619 return *this;
1620}
1621
1622inline sc_fxnum_subref &
1623sc_fxnum_subref::operator = (const sc_fxnum_fast_subref &a)
1624{
1625 m_bv = static_cast<sc_bv_base>(a);
1626 set();
1627 SC_FXNUM_OBSERVER_WRITE_(m_num)
1628 return *this;
1629}
1630
1631#define DEFN_ASN_OP_T(tp) \
1632inline sc_fxnum_subref & \
1633sc_fxnum_subref::operator = (tp a) \
1634{ \
1635 m_bv = a; \
1636 set(); \
1637 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1638 return *this; \
1639}
1640
1641DEFN_ASN_OP_T(const sc_bv_base &)
1642DEFN_ASN_OP_T(const sc_lv_base &)
1643DEFN_ASN_OP_T(const char *)
1644DEFN_ASN_OP_T(const bool *)
1645DEFN_ASN_OP_T(const sc_signed &)
1646DEFN_ASN_OP_T(const sc_unsigned &)
1647DEFN_ASN_OP_T(const sc_int_base &)
1648DEFN_ASN_OP_T(const sc_uint_base &)
1649DEFN_ASN_OP_T(int64)
1650DEFN_ASN_OP_T(uint64)
1651DEFN_ASN_OP_T(int)
1652DEFN_ASN_OP_T(unsigned int)
1653DEFN_ASN_OP_T(long)
1654DEFN_ASN_OP_T(unsigned long)
1655DEFN_ASN_OP_T(char)
1656
1657#undef DEFN_ASN_OP_T
1658
1659#define DEFN_ASN_OP_T(op, tp) \
1660inline sc_fxnum_subref & \
1661sc_fxnum_subref::operator op ## = (tp a) \
1662{ \
1663 SC_FXNUM_OBSERVER_READ_(m_num) \
1664 get(); \
1665 m_bv = m_bv op a; \
1666 set(); \
1667 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1668 return *this; \
1669}
1670
1671#define DEFN_ASN_OP(op) \
1672inline sc_fxnum_subref & \
1673sc_fxnum_subref::operator op ## = (const sc_fxnum_subref &a) \
1674{ \
1675 SC_FXNUM_OBSERVER_READ_(m_num) \
1676 get(); \
1677 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1678 set(); \
1679 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1680 return *this; \
1681} \
1682 \
1683inline sc_fxnum_subref & \
1684sc_fxnum_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1685{ \
1686 SC_FXNUM_OBSERVER_READ_(m_num) \
1687 get(); \
1688 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1689 set(); \
1690 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1691 return *this; \
1692} \
1693 \
1694DEFN_ASN_OP_T(op, const sc_bv_base &) \
1695DEFN_ASN_OP_T(op, const sc_lv_base &)
1696
1697DEFN_ASN_OP( &)
1698DEFN_ASN_OP(|)
1699DEFN_ASN_OP(^)
1700
1701#undef DEFN_ASN_OP_T
1702#undef DEFN_ASN_OP
1703
1704// relational operators
1705#define DEFN_REL_OP_T(op, tp) \
1706inline bool \
1707operator op (const sc_fxnum_subref &a, tp b) \
1708{ \
1709 return (static_cast<sc_bv_base>(a) op b); \
1710} \
1711 \
1712inline bool \
1713operator op (tp a, const sc_fxnum_subref &b) \
1714{ \
1715 return (static_cast<sc_bv_base>(b) op a); \
1716}
1717
1718#define DEFN_REL_OP(op) \
1719inline bool \
1720operator op (const sc_fxnum_subref &a, const sc_fxnum_subref &b) \
1721{ \
1722 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1723} \
1724 \
1725inline bool \
1726operator op (const sc_fxnum_subref &a, const sc_fxnum_fast_subref &b) \
1727{ \
1728 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1729} \
1730 \
1731DEFN_REL_OP_T(op, const sc_bv_base &) \
1732DEFN_REL_OP_T(op, const sc_lv_base &) \
1733DEFN_REL_OP_T(op, const char *) \
1734DEFN_REL_OP_T(op, const bool *) \
1735DEFN_REL_OP_T(op, const sc_signed &) \
1736DEFN_REL_OP_T(op, const sc_unsigned &) \
1737DEFN_REL_OP_T(op, int) \
1738DEFN_REL_OP_T(op, unsigned int) \
1739DEFN_REL_OP_T(op, long) \
1740DEFN_REL_OP_T(op, unsigned long)
1741
1742DEFN_REL_OP(==)
1743DEFN_REL_OP(!=)
1744
1745#undef DEFN_REL_OP_T
1746#undef DEFN_REL_OP
1747
1748
1749// reduce functions
1750
1751#define DEFN_RED_FNC(fnc) \
1752inline bool \
1753sc_fxnum_subref::fnc() const \
1754{ \
1755 SC_FXNUM_OBSERVER_READ_(m_num) \
1756 get(); \
1757 return static_cast<bool>(m_bv.fnc()); \
1758}
1759
1760DEFN_RED_FNC(and_reduce)
1761DEFN_RED_FNC(nand_reduce)
1762DEFN_RED_FNC(or_reduce)
1763DEFN_RED_FNC(nor_reduce)
1764DEFN_RED_FNC(xor_reduce)
1765DEFN_RED_FNC(xnor_reduce)
1766
1767#undef DEFN_RED_FNC
1768
1769// query parameter
1770inline int
1771sc_fxnum_subref::length() const
1772{
1773 return m_bv.length();
1774}
1775
1776// explicit conversions
1777inline int
1778sc_fxnum_subref::to_int() const
1779{
1780 SC_FXNUM_OBSERVER_READ_(m_num)
1781 get();
1782 return m_bv.to_int();
1783}
1784
1785inline int64
1786sc_fxnum_subref::to_int64() const
1787{
1788 SC_FXNUM_OBSERVER_READ_(m_num)
1789 get();
1790 return m_bv.to_int64();
1791}
1792
1793inline unsigned int
1794sc_fxnum_subref::to_uint() const
1795{
1796 SC_FXNUM_OBSERVER_READ_(m_num)
1797 get();
1798 return m_bv.to_uint();
1799}
1800
1801inline uint64
1802sc_fxnum_subref::to_uint64() const
1803{
1804 SC_FXNUM_OBSERVER_READ_(m_num)
1805 get();
1806 return m_bv.to_uint64();
1807}
1808
1809inline long
1810sc_fxnum_subref::to_long() const
1811{
1812 SC_FXNUM_OBSERVER_READ_(m_num)
1813 get();
1814 return m_bv.to_long();
1815}
1816
1817inline unsigned long
1818sc_fxnum_subref::to_ulong() const
1819{
1820 SC_FXNUM_OBSERVER_READ_(m_num)
1821 get();
1822 return m_bv.to_ulong();
1823}
1824
1825
1826inline const std::string
1827sc_fxnum_subref::to_string() const
1828{
1829 get();
1830 return m_bv.to_string();
1831}
1832
1833inline const std::string
1834sc_fxnum_subref::to_string(sc_numrep numrep) const
1835{
1836 get();
1837 return m_bv.to_string(numrep);
1838}
1839
1840inline const std::string
1841sc_fxnum_subref::to_string(sc_numrep numrep, bool w_prefix) const
1842{
1843 get();
1844 return m_bv.to_string(numrep, w_prefix);
1845}
1846
1847
1848// implicit conversion
1849inline sc_fxnum_subref::operator sc_bv_base () const
1850{
1851 SC_FXNUM_OBSERVER_READ_(m_num)
1852 get();
1853 return m_bv;
1854}
1855
1856
1857inline ::std::ostream &
1858operator << (::std::ostream &os, const sc_fxnum_subref &a)
1859{
1860 a.print(os);
1861 return os;
1862}
1863
1864inline ::std::istream &
1865operator >> (::std::istream &is, sc_fxnum_subref &a)
1866{
1867 a.scan(is);
1868 return is;
1869}
1870
1871
1872// ----------------------------------------------------------------------------
1873// CLASS : sc_fxnum_fast_subref
1874//
1875// Proxy class for part-selection in class sc_fxnum_fast,
1876// behaves like sc_bv_base.
1877// ----------------------------------------------------------------------------
1878
1879// constructor
1880
1881inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1882 sc_fxnum_fast &num_, int from_, int to_) :
1883 m_num(num_), m_from(from_), m_to(to_),
1884 m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1885{}
1886
1887
1888// copy constructor
1889inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1890 const sc_fxnum_fast_subref &a) :
1891 m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1892 m_bv(*new sc_bv_base(a.m_bv))
1893{}
1894
1895
1896// destructor
1897inline sc_fxnum_fast_subref::~sc_fxnum_fast_subref()
1898{
1899 delete &m_bv;
1900}
1901
1902
1903// assignment operators
1904inline sc_fxnum_fast_subref &
1905sc_fxnum_fast_subref::operator = (const sc_fxnum_subref &a)
1906{
1907 m_bv = static_cast<sc_bv_base>(a);
1908 set();
1909 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1910 return *this;
1911}
1912
1913inline sc_fxnum_fast_subref &
1914sc_fxnum_fast_subref::operator = (const sc_fxnum_fast_subref &a)
1915{
1916 if (&a != this) {
1917 m_bv = static_cast<sc_bv_base>(a);
1918 set();
1919 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1920 }
1921 return *this;
1922}
1923
1924#define DEFN_ASN_OP_T(tp) \
1925inline sc_fxnum_fast_subref & \
1926sc_fxnum_fast_subref::operator = (tp a) \
1927{ \
1928 m_bv = a; \
1929 set(); \
1930 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1931 return *this; \
1932}
1933
1934DEFN_ASN_OP_T(const sc_bv_base &)
1935DEFN_ASN_OP_T(const sc_lv_base &)
1936DEFN_ASN_OP_T(const char *)
1937DEFN_ASN_OP_T(const bool *)
1938DEFN_ASN_OP_T(const sc_signed &)
1939DEFN_ASN_OP_T(const sc_unsigned &)
1940DEFN_ASN_OP_T(const sc_int_base &)
1941DEFN_ASN_OP_T(const sc_uint_base &)
1942DEFN_ASN_OP_T(int64)
1943DEFN_ASN_OP_T(uint64)
1944DEFN_ASN_OP_T(int)
1945DEFN_ASN_OP_T(unsigned int)
1946DEFN_ASN_OP_T(long)
1947DEFN_ASN_OP_T(unsigned long)
1948DEFN_ASN_OP_T(char)
1949
1950#undef DEFN_ASN_OP_T
1951
1952
1953#define DEFN_ASN_OP_T(op, tp) \
1954inline sc_fxnum_fast_subref & \
1955sc_fxnum_fast_subref::operator op ## = (tp a) \
1956{ \
1957 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1958 get(); \
1959 m_bv = m_bv op a; \
1960 set(); \
1961 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1962 return *this; \
1963}
1964
1965#define DEFN_ASN_OP(op) \
1966inline sc_fxnum_fast_subref & \
1967sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_subref &a) \
1968{ \
1969 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1970 get(); \
1971 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1972 set(); \
1973 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1974 return *this; \
1975} \
1976 \
1977inline sc_fxnum_fast_subref & \
1978sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1979{ \
1980 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1981 get(); \
1982 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1983 set(); \
1984 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1985 return *this; \
1986} \
1987 \
1988DEFN_ASN_OP_T(op, const sc_bv_base &) \
1989DEFN_ASN_OP_T(op, const sc_lv_base &)
1990
1991DEFN_ASN_OP(&)
1992DEFN_ASN_OP(|)
1993DEFN_ASN_OP(^)
1994
1995#undef DEFN_ASN_OP_T
1996#undef DEFN_ASN_OP
1997
1998
1999// relational operators
2000
2001#define DEFN_REL_OP_T(op, tp) \
2002inline bool \
2003operator op (const sc_fxnum_fast_subref &a, tp b) \
2004{ \
2005 return (static_cast<sc_bv_base>(a) op b); \
2006} \
2007 \
2008inline bool \
2009operator op (tp a, const sc_fxnum_fast_subref &b) \
2010{ \
2011 return (static_cast<sc_bv_base>(b) op a); \
2012}
2013
2014#define DEFN_REL_OP(op) \
2015inline bool \
2016operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_fast_subref &b) \
2017{ \
2018 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2019} \
2020 \
2021inline bool \
2022operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_subref &b) \
2023{ \
2024 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2025} \
2026 \
2027DEFN_REL_OP_T(op, const sc_bv_base &) \
2028DEFN_REL_OP_T(op, const sc_lv_base &) \
2029DEFN_REL_OP_T(op, const char *) \
2030DEFN_REL_OP_T(op, const bool *) \
2031DEFN_REL_OP_T(op, const sc_signed &) \
2032DEFN_REL_OP_T(op, const sc_unsigned &) \
2033DEFN_REL_OP_T(op, int) \
2034DEFN_REL_OP_T(op, unsigned int) \
2035DEFN_REL_OP_T(op, long) \
2036DEFN_REL_OP_T(op, unsigned long)
2037
2038DEFN_REL_OP(==)
2039DEFN_REL_OP(!=)
2040
2041#undef DEFN_REL_OP_T
2042#undef DEFN_REL_OP
2043
2044// reduce functions
2045#define DEFN_RED_FNC(fnc) \
2046inline bool \
2047sc_fxnum_fast_subref::fnc() const \
2048{ \
2049 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
2050 get(); \
2051 return static_cast<bool>(m_bv.fnc()); \
2052}
2053
2054DEFN_RED_FNC(and_reduce)
2055DEFN_RED_FNC(nand_reduce)
2056DEFN_RED_FNC(or_reduce)
2057DEFN_RED_FNC(nor_reduce)
2058DEFN_RED_FNC(xor_reduce)
2059DEFN_RED_FNC(xnor_reduce)
2060
2061#undef DEFN_RED_FNC
2062
2063// query parameter
2064inline int
2065sc_fxnum_fast_subref::length() const
2066{
2067 return m_bv.length();
2068}
2069
2070// explicit conversions
2071inline int
2072sc_fxnum_fast_subref::to_int() const
2073{
2074 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2075 get();
2076 return m_bv.to_int();
2077}
2078
2079inline int64
2080sc_fxnum_fast_subref::to_int64() const
2081{
2082 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2083 get();
2084 return m_bv.to_int64();
2085}
2086
2087inline unsigned int
2088sc_fxnum_fast_subref::to_uint() const
2089{
2090 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2091 get();
2092 return m_bv.to_uint();
2093}
2094
2095inline uint64
2096sc_fxnum_fast_subref::to_uint64() const
2097{
2098 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2099 get();
2100 return m_bv.to_uint64();
2101}
2102
2103inline long
2104sc_fxnum_fast_subref::to_long() const
2105{
2106 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2107 get();
2108 return m_bv.to_long();
2109}
2110
2111inline unsigned long
2112sc_fxnum_fast_subref::to_ulong() const
2113{
2114 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2115 get();
2116 return m_bv.to_ulong();
2117}
2118
2119inline const std::string
2120sc_fxnum_fast_subref::to_string() const
2121{
2122 get();
2123 return m_bv.to_string();
2124}
2125
2126inline const std::string
2127sc_fxnum_fast_subref::to_string(sc_numrep numrep) const
2128{
2129 get();
2130 return m_bv.to_string(numrep);
2131}
2132
2133inline const std::string
2134sc_fxnum_fast_subref::to_string(sc_numrep numrep, bool w_prefix) const
2135{
2136 get();
2137 return m_bv.to_string(numrep, w_prefix);
2138}
2139
2140
2141// implicit conversion
2142inline sc_fxnum_fast_subref::operator sc_bv_base () const
2143{
2144 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2145 get();
2146 return m_bv;
2147}
2148
2149inline ::std::ostream &
2150operator << (::std::ostream &os, const sc_fxnum_fast_subref &a)
2151{
2152 a.print(os);
2153 return os;
2154}
2155
2156inline ::std::istream &
2157operator >> (::std::istream &is, sc_fxnum_fast_subref &a)
2158{
2159 a.scan(is);
2160 return is;
2161}
2162
2163
2164// ----------------------------------------------------------------------------
2165// CLASS : sc_fxnum
2166//
2167// Base class for the fixed-point types; arbitrary precision.
2168// ----------------------------------------------------------------------------
2169
2170inline sc_fxnum_observer *
2171sc_fxnum::observer() const
2172{
2173 return m_observer;
2174}
2175
2176inline void
2177sc_fxnum::cast()
2178{
2179 SC_ERROR_IF_(!m_rep->is_normal(), "invalid fixed-point value");
2180
2181 if (m_params.cast_switch() == SC_ON)
2182 m_rep->cast(m_params, m_q_flag, m_o_flag);
2183}
2184
2185// constructors
2186inline sc_fxnum::sc_fxnum(const sc_fxtype_params &type_params_,
2187 sc_enc enc_, const sc_fxcast_switch &cast_sw,
2188 sc_fxnum_observer *observer_) :
2189 m_rep(new scfx_rep), m_params(type_params_, enc_, cast_sw),
2190 m_q_flag(false), m_o_flag(false), m_observer(observer_)
2191{
2192 SC_FXNUM_OBSERVER_DEFAULT_
2193 SC_FXNUM_OBSERVER_CONSTRUCT_(*this)
2194}
2195
2196#define DEFN_CTOR_T(tp, arg) \
2197inline sc_fxnum::sc_fxnum(tp a, const sc_fxtype_params &type_params_, \
2198 sc_enc enc_, const sc_fxcast_switch &cast_sw, \
2199 sc_fxnum_observer *observer_) : \
2200 m_rep(new scfx_rep(arg)), m_params(type_params_, enc_, cast_sw), \
2201 m_q_flag(false), m_o_flag(false), m_observer(observer_) \
2202{ \
2203 SC_FXNUM_OBSERVER_DEFAULT_ \
2204 cast(); \
2205 SC_FXNUM_OBSERVER_CONSTRUCT_(*this) \
2206 SC_FXNUM_OBSERVER_WRITE_(*this) \
2207}
2208
2209#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, a)
2210#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, *a.m_rep)
2211#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
2212#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp, a.value())
2213
2214DEFN_CTOR_T_A(int)
2215DEFN_CTOR_T_A(unsigned int)
2216DEFN_CTOR_T_A(long)
2217DEFN_CTOR_T_A(unsigned long)
2218DEFN_CTOR_T_A(float)
2219DEFN_CTOR_T_A(double)
2220DEFN_CTOR_T_A(const char *)
2221DEFN_CTOR_T_B(const sc_fxval &)
2222DEFN_CTOR_T_C(const sc_fxval_fast &)
2223DEFN_CTOR_T_B(const sc_fxnum &)
2224DEFN_CTOR_T_C(const sc_fxnum_fast &)
2225#ifndef SC_FX_EXCLUDE_OTHER
2226DEFN_CTOR_T_A(int64)
2227DEFN_CTOR_T_A(uint64)
2228DEFN_CTOR_T_D(const sc_int_base &)
2229DEFN_CTOR_T_D(const sc_uint_base &)
2230DEFN_CTOR_T_A(const sc_signed &)
2231DEFN_CTOR_T_A(const sc_unsigned &)
2232#endif
2233
2234#undef DEFN_CTOR_T
2235#undef DEFN_CTOR_T_A
2236#undef DEFN_CTOR_T_B
2237#undef DEFN_CTOR_T_C
2238#undef DEFN_CTOR_T_D
2239
2240inline sc_fxnum::~sc_fxnum()
2241{
2242 SC_FXNUM_OBSERVER_DESTRUCT_(*this)
2243 delete m_rep;
2244}
2245
2246// internal use only;
2247inline const scfx_rep *
2248sc_fxnum::get_rep() const
2249{
2250 SC_FXNUM_OBSERVER_READ_(*this)
2251 return m_rep;
2252}
2253
2254// unary operators
2255inline const sc_fxval
2256sc_fxnum::operator - () const
2257{
2258 SC_FXNUM_OBSERVER_READ_(*this)
2259 return sc_fxval(sc_dt::neg_scfx_rep(*m_rep));
2260}
2261
2262inline const sc_fxval
2263sc_fxnum::operator + () const
2264{
2265 SC_FXNUM_OBSERVER_READ_(*this)
2266 return sc_fxval(new scfx_rep(*m_rep));
2267}
2268
2269// unary functions
2270inline void
2271neg(sc_fxval &c, const sc_fxnum &a)
2272{
2273 SC_FXNUM_OBSERVER_READ_(a)
2274 c.set_rep(sc_dt::neg_scfx_rep(*a.m_rep));
2275}
2276
2277inline void
2278neg(sc_fxnum &c, const sc_fxnum &a)
2279{
2280 SC_FXNUM_OBSERVER_READ_(a)
2281 delete c.m_rep;
2282 c.m_rep = sc_dt::neg_scfx_rep(*a.m_rep);
2283 c.cast();
2284 SC_FXNUM_OBSERVER_WRITE_(c)
2285}
2286
2287// binary operators
2288#define DEFN_BIN_OP_T(op, fnc, tp) \
2289inline const sc_fxval \
2290operator op (const sc_fxnum &a, tp b) \
2291{ \
2292 SC_FXNUM_OBSERVER_READ_(a) \
2293 sc_fxval tmp(b); \
2294 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2295} \
2296 \
2297inline const sc_fxval \
2298operator op (tp a, const sc_fxnum &b) \
2299{ \
2300 SC_FXNUM_OBSERVER_READ_(b) \
2301 sc_fxval tmp(a); \
2302 return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2303}
2304
2305#ifndef SC_FX_EXCLUDE_OTHER
2306#define DEFN_BIN_OP_OTHER(op, fnc) \
2307DEFN_BIN_OP_T(op, fnc, int64) \
2308DEFN_BIN_OP_T(op, fnc, uint64) \
2309DEFN_BIN_OP_T(op, fnc, const sc_int_base &) \
2310DEFN_BIN_OP_T(op, fnc, const sc_uint_base &) \
2311DEFN_BIN_OP_T(op, fnc, const sc_signed &) \
2312DEFN_BIN_OP_T(op, fnc, const sc_unsigned &)
2313#else
2314#define DEFN_BIN_OP_OTHER(op, fnc)
2315#endif
2316
2317#define DEFN_BIN_OP(op, fnc) \
2318inline const sc_fxval \
2319operator op (const sc_fxnum &a, const sc_fxnum &b) \
2320{ \
2321 SC_FXNUM_OBSERVER_READ_(a) \
2322 SC_FXNUM_OBSERVER_READ_(b) \
2323 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2324} \
2325 \
2326inline const sc_fxval \
2327operator op (const sc_fxnum &a, const sc_fxval &b) \
2328{ \
2329 SC_FXNUM_OBSERVER_READ_(a) \
2330 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2331} \
2332 \
2333inline const sc_fxval \
2334operator op (const sc_fxval &a, const sc_fxnum &b) \
2335{ \
2336 SC_FXNUM_OBSERVER_READ_(b) \
2337 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2338} \
2339 \
2340DEFN_BIN_OP_T(op, fnc, int) \
2341DEFN_BIN_OP_T(op, fnc, unsigned int) \
2342DEFN_BIN_OP_T(op, fnc, long) \
2343DEFN_BIN_OP_T(op, fnc, unsigned long) \
2344DEFN_BIN_OP_T(op, fnc, float) \
2345DEFN_BIN_OP_T(op, fnc, double) \
2346DEFN_BIN_OP_T(op, fnc, const char *) \
2347DEFN_BIN_OP_T(op, fnc, const sc_fxval_fast &) \
2348DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &) \
2349DEFN_BIN_OP_OTHER(op, fnc)
2350
2351DEFN_BIN_OP(*, mult)
2352DEFN_BIN_OP(+, add)
2353DEFN_BIN_OP(-, sub)
2354// don't use macros
2355//DEFN_BIN_OP(/, div)
2356inline const sc_fxval
2357operator / (const sc_fxnum &a, const sc_fxnum &b)
2358{
2359 SC_FXNUM_OBSERVER_READ_(a)
2360 SC_FXNUM_OBSERVER_READ_(b)
2361 return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.m_rep));
2362}
2363
2364inline const sc_fxval
2365operator / (const sc_fxnum &a, const sc_fxval &b)
2366{
2367 SC_FXNUM_OBSERVER_READ_(a)
2368 return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.get_rep()));
2369}
2370
2371inline const sc_fxval
2372operator / (const sc_fxval &a, const sc_fxnum &b)
2373{
2374 SC_FXNUM_OBSERVER_READ_(b)
2375 return sc_fxval(sc_dt::div_scfx_rep(*a.get_rep(), *b.m_rep));
2376}
2377
2378DEFN_BIN_OP_T(/, div, int)
2379DEFN_BIN_OP_T(/, div, unsigned int)
2380DEFN_BIN_OP_T(/, div, long)
2381DEFN_BIN_OP_T(/, div, unsigned long)
2382DEFN_BIN_OP_T(/, div, float)
2383DEFN_BIN_OP_T(/, div, double)
2384DEFN_BIN_OP_T(/, div, const char *)
2385DEFN_BIN_OP_T(/, div, const sc_fxval_fast &)
2386DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
2387//DEFN_BIN_OP_OTHER(/, div)
2388
2389DEFN_BIN_OP_T(/, div, int64)
2390DEFN_BIN_OP_T(/, div, uint64)
2391DEFN_BIN_OP_T(/, div, const sc_int_base &)
2392DEFN_BIN_OP_T(/, div, const sc_uint_base &)
2393DEFN_BIN_OP_T(/, div, const sc_signed &)
2394DEFN_BIN_OP_T(/, div, const sc_unsigned &)
2395
2396#undef DEFN_BIN_OP_T
2397#undef DEFN_BIN_OP_OTHER
2398#undef DEFN_BIN_OP
2399
2400inline const sc_fxval
2401operator << (const sc_fxnum &a, int b)
2402{
2403 SC_FXNUM_OBSERVER_READ_(a)
2404 return sc_fxval(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2405}
2406
2407inline const sc_fxval
2408operator >> (const sc_fxnum &a, int b)
2409{
2410 SC_FXNUM_OBSERVER_READ_(a)
2411 return sc_fxval(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2412}
2413
2414// binary functions
2415#define DEFN_BIN_FNC_T(fnc, tp) \
2416inline void \
2417fnc (sc_fxval &c, const sc_fxnum &a, tp b) \
2418{ \
2419 SC_FXNUM_OBSERVER_READ_(a) \
2420 sc_fxval tmp(b); \
2421 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2422} \
2423 \
2424inline void \
2425fnc (sc_fxval &c, tp a, const sc_fxnum &b) \
2426{ \
2427 SC_FXNUM_OBSERVER_READ_(b) \
2428 sc_fxval tmp(a); \
2429 c.set_rep(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2430} \
2431 \
2432inline void \
2433fnc (sc_fxnum &c, const sc_fxnum &a, tp b) \
2434{ \
2435 SC_FXNUM_OBSERVER_READ_(a) \
2436 sc_fxval tmp(b); \
2437 delete c.m_rep; \
2438 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep()); \
2439 c.cast(); \
2440 SC_FXNUM_OBSERVER_WRITE_(c) \
2441} \
2442 \
2443inline void \
2444fnc (sc_fxnum &c, tp a, const sc_fxnum &b) \
2445{ \
2446 SC_FXNUM_OBSERVER_READ_(b) \
2447 sc_fxval tmp(a); \
2448 delete c.m_rep; \
2449 c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep); \
2450 c.cast(); \
2451 SC_FXNUM_OBSERVER_WRITE_(c) \
2452}
2453
2454#define DEFN_BIN_FNC_OTHER(fnc) \
2455DEFN_BIN_FNC_T(fnc, int64) \
2456DEFN_BIN_FNC_T(fnc, uint64) \
2457DEFN_BIN_FNC_T(fnc, const sc_int_base &) \
2458DEFN_BIN_FNC_T(fnc, const sc_uint_base &) \
2459DEFN_BIN_FNC_T(fnc, const sc_signed &) \
2460DEFN_BIN_FNC_T(fnc, const sc_unsigned &)
2461
2462#define DEFN_BIN_FNC(fnc) \
2463inline void \
2464fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxnum &b) \
2465{ \
2466 SC_FXNUM_OBSERVER_READ_(a) \
2467 SC_FXNUM_OBSERVER_READ_(b) \
2468 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2469} \
2470 \
2471inline void \
2472fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxnum &b) \
2473{ \
2474 SC_FXNUM_OBSERVER_READ_(a) \
2475 SC_FXNUM_OBSERVER_READ_(b) \
2476 delete c.m_rep; \
2477 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep); \
2478 c.cast(); \
2479 SC_FXNUM_OBSERVER_WRITE_(c) \
2480} \
2481 \
2482inline void \
2483fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxval &b) \
2484{ \
2485 SC_FXNUM_OBSERVER_READ_(a) \
2486 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2487} \
2488 \
2489inline void \
2490fnc (sc_fxval &c, const sc_fxval &a, const sc_fxnum &b) \
2491{ \
2492 SC_FXNUM_OBSERVER_READ_(b) \
2493 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2494} \
2495 \
2496inline void \
2497fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxval &b) \
2498{ \
2499 SC_FXNUM_OBSERVER_READ_(a) \
2500 delete c.m_rep; \
2501 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep()); \
2502 c.cast(); \
2503 SC_FXNUM_OBSERVER_WRITE_(c) \
2504} \
2505 \
2506inline void \
2507fnc (sc_fxnum &c, const sc_fxval &a, const sc_fxnum &b) \
2508{ \
2509 SC_FXNUM_OBSERVER_READ_(b) \
2510 delete c.m_rep; \
2511 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep); \
2512 c.cast(); \
2513 SC_FXNUM_OBSERVER_WRITE_(c) \
2514} \
2515 \
2516DEFN_BIN_FNC_T(fnc, int) \
2517DEFN_BIN_FNC_T(fnc, unsigned int) \
2518DEFN_BIN_FNC_T(fnc, long) \
2519DEFN_BIN_FNC_T(fnc, unsigned long) \
2520DEFN_BIN_FNC_T(fnc, float) \
2521DEFN_BIN_FNC_T(fnc, double) \
2522DEFN_BIN_FNC_T(fnc, const char *) \
2523DEFN_BIN_FNC_T(fnc, const sc_fxval_fast &) \
2524DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
2525DEFN_BIN_FNC_OTHER(fnc)
2526
2527DEFN_BIN_FNC(mult)
2528DEFN_BIN_FNC(div)
2529DEFN_BIN_FNC(add)
2530DEFN_BIN_FNC(sub)
2531
2532#undef DEFN_BIN_FNC_T
2533#undef DEFN_BIN_FNC_OTHER
2534#undef DEFN_BIN_FNC
2535
2536inline void
2537lshift(sc_fxval &c, const sc_fxnum &a, int b)
2538{
2539 SC_FXNUM_OBSERVER_READ_(a)
2540 c.set_rep(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2541}
2542
2543inline void
2544rshift(sc_fxval &c, const sc_fxnum &a, int b)
2545{
2546 SC_FXNUM_OBSERVER_READ_(a)
2547 c.set_rep(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2548}
2549
2550inline void
2551lshift(sc_fxnum &c, const sc_fxnum &a, int b)
2552{
2553 SC_FXNUM_OBSERVER_READ_(a)
2554 delete c.m_rep;
2555 c.m_rep = sc_dt::lsh_scfx_rep(*a.m_rep, b);
2556 c.cast();
2557 SC_FXNUM_OBSERVER_WRITE_(c)
2558}
2559
2560inline void
2561rshift(sc_fxnum &c, const sc_fxnum &a, int b)
2562{
2563 SC_FXNUM_OBSERVER_READ_(a)
2564 delete c.m_rep;
2565 c.m_rep = sc_dt::rsh_scfx_rep(*a.m_rep, b);
2566 c.cast();
2567 SC_FXNUM_OBSERVER_WRITE_(c)
2568}
2569
2570// relational (including equality) operators
2571#define DEFN_REL_OP_T(op, ret, tp) \
2572inline bool \
2573operator op (const sc_fxnum &a, tp b) \
2574{ \
2575 SC_FXNUM_OBSERVER_READ_(a) \
2576 sc_fxval tmp(b); \
2577 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.get_rep()); \
2578 return (ret); \
2579} \
2580 \
2581inline bool \
2582operator op (tp a, const sc_fxnum &b) \
2583{ \
2584 SC_FXNUM_OBSERVER_READ_(b) \
2585 sc_fxval tmp(a); \
2586 int result = sc_dt::cmp_scfx_rep(*tmp.get_rep(), *b.m_rep); \
2587 return (ret); \
2588}
2589
2590#define DEFN_REL_OP_OTHER(op, ret) \
2591DEFN_REL_OP_T(op, ret, int64) \
2592DEFN_REL_OP_T(op, ret, uint64) \
2593DEFN_REL_OP_T(op, ret, const sc_int_base &) \
2594DEFN_REL_OP_T(op, ret, const sc_uint_base &) \
2595DEFN_REL_OP_T(op, ret, const sc_signed &) \
2596DEFN_REL_OP_T(op, ret, const sc_unsigned &)
2597
2598#define DEFN_REL_OP(op, ret) \
2599inline bool \
2600operator op (const sc_fxnum &a, const sc_fxnum &b) \
2601{ \
2602 SC_FXNUM_OBSERVER_READ_(a) \
2603 SC_FXNUM_OBSERVER_READ_(b) \
2604 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.m_rep); \
2605 return (ret); \
2606} \
2607 \
2608inline bool \
2609operator op (const sc_fxnum &a, const sc_fxval &b) \
2610{ \
2611 SC_FXNUM_OBSERVER_READ_(a) \
2612 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.get_rep()); \
2613 return (ret); \
2614} \
2615 \
2616inline bool \
2617operator op (const sc_fxval &a, const sc_fxnum &b) \
2618{ \
2619 SC_FXNUM_OBSERVER_READ_(b) \
2620 int result = sc_dt::cmp_scfx_rep(*a.get_rep(), *b.m_rep); \
2621 return (ret); \
2622} \
2623 \
2624DEFN_REL_OP_T(op, ret, int) \
2625DEFN_REL_OP_T(op, ret, unsigned int) \
2626DEFN_REL_OP_T(op, ret, long) \
2627DEFN_REL_OP_T(op, ret, unsigned long) \
2628DEFN_REL_OP_T(op, ret, float) \
2629DEFN_REL_OP_T(op, ret, double) \
2630DEFN_REL_OP_T(op, ret, const char *) \
2631DEFN_REL_OP_T(op, ret, const sc_fxval_fast &) \
2632DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &) \
2633DEFN_REL_OP_OTHER(op, ret)
2634
2635DEFN_REL_OP(<, result < 0)
2636DEFN_REL_OP(<=, result <= 0)
2637DEFN_REL_OP(>, result > 0 && result != 2)
2638DEFN_REL_OP(>=, result >= 0 && result != 2)
2639DEFN_REL_OP(==, result == 0)
2640DEFN_REL_OP(!=, result != 0)
2641
2642#undef DEFN_REL_OP_T
2643#undef DEFN_REL_OP_OTHER
2644#undef DEFN_REL_OP
2645
2646// assignment operators
2647inline sc_fxnum &
2648sc_fxnum::operator = (const sc_fxnum &a)
2649{
2650 if (&a != this) {
2651 SC_FXNUM_OBSERVER_READ_(a)
2652 *m_rep = *a.m_rep;
2653 cast();
2654 SC_FXNUM_OBSERVER_WRITE_(*this)
2655 }
2656 return *this;
2657}
2658
2659inline sc_fxnum &
2660sc_fxnum::operator = (const sc_fxval &a)
2661{
2662 *m_rep = *a.get_rep();
2663 cast();
2664 SC_FXNUM_OBSERVER_WRITE_(*this)
2665 return *this;
2666}
2667
2668#define DEFN_ASN_OP_T(tp) \
2669inline sc_fxnum & \
2670sc_fxnum::operator = (tp a) \
2671{ \
2672 sc_fxval tmp(a); \
2673 *m_rep = *tmp.get_rep(); \
2674 cast(); \
2675 SC_FXNUM_OBSERVER_WRITE_(*this) \
2676 return *this; \
2677}
2678
2679DEFN_ASN_OP_T(int)
2680DEFN_ASN_OP_T(unsigned int)
2681DEFN_ASN_OP_T(long)
2682DEFN_ASN_OP_T(unsigned long)
2683DEFN_ASN_OP_T(float)
2684DEFN_ASN_OP_T(double)
2685DEFN_ASN_OP_T(const char *)
2686DEFN_ASN_OP_T(const sc_fxval_fast &)
2687DEFN_ASN_OP_T(const sc_fxnum_fast &)
2688
2689DEFN_ASN_OP_T(int64)
2690DEFN_ASN_OP_T(uint64)
2691DEFN_ASN_OP_T(const sc_int_base &)
2692DEFN_ASN_OP_T(const sc_uint_base &)
2693DEFN_ASN_OP_T(const sc_signed &)
2694DEFN_ASN_OP_T(const sc_unsigned &)
2695
2696#undef DEFN_ASN_OP_T
2697
2698
2699#define DEFN_ASN_OP_T(op, fnc, tp) \
2700inline sc_fxnum & \
2701sc_fxnum::operator op (tp b) \
2702{ \
2703 SC_FXNUM_OBSERVER_READ_(*this) \
2704 sc_fxval tmp(b); \
2705 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.get_rep()); \
2706 delete m_rep; \
2707 m_rep = new_rep; \
2708 cast(); \
2709 SC_FXNUM_OBSERVER_WRITE_(*this) \
2710 return *this; \
2711}
2712
2713#define DEFN_ASN_OP_OTHER(op, fnc) \
2714DEFN_ASN_OP_T(op, fnc, int64) \
2715DEFN_ASN_OP_T(op, fnc, uint64) \
2716DEFN_ASN_OP_T(op, fnc, const sc_int_base &) \
2717DEFN_ASN_OP_T(op, fnc, const sc_uint_base &) \
2718DEFN_ASN_OP_T(op, fnc, const sc_signed &) \
2719DEFN_ASN_OP_T(op, fnc, const sc_unsigned &)
2720
2721#define DEFN_ASN_OP(op, fnc) \
2722inline sc_fxnum & \
2723sc_fxnum::operator op (const sc_fxnum &b) \
2724{ \
2725 SC_FXNUM_OBSERVER_READ_(*this) \
2726 SC_FXNUM_OBSERVER_READ_(b) \
2727 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.m_rep); \
2728 delete m_rep; \
2729 m_rep = new_rep; \
2730 cast(); \
2731 SC_FXNUM_OBSERVER_WRITE_(*this) \
2732 return *this; \
2733} \
2734 \
2735inline sc_fxnum & \
2736sc_fxnum::operator op (const sc_fxval &b) \
2737{ \
2738 SC_FXNUM_OBSERVER_READ_(*this) \
2739 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
2740 delete m_rep; \
2741 m_rep = new_rep; \
2742 cast(); \
2743 SC_FXNUM_OBSERVER_WRITE_(*this) \
2744 return *this; \
2745} \
2746 \
2747DEFN_ASN_OP_T(op, fnc, int) \
2748DEFN_ASN_OP_T(op, fnc, unsigned int) \
2749DEFN_ASN_OP_T(op, fnc, long) \
2750DEFN_ASN_OP_T(op, fnc, unsigned long) \
2751DEFN_ASN_OP_T(op, fnc, float) \
2752DEFN_ASN_OP_T(op, fnc, double) \
2753DEFN_ASN_OP_T(op, fnc, const char *) \
2754DEFN_ASN_OP_T(op, fnc, const sc_fxval_fast &) \
2755DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &) \
2756DEFN_ASN_OP_OTHER(op, fnc)
2757
2758DEFN_ASN_OP(*=, mult)
2759DEFN_ASN_OP(/=, div)
2760DEFN_ASN_OP(+=, add)
2761DEFN_ASN_OP(-=, sub)
2762
2763#undef DEFN_ASN_OP_T
2764#undef DEFN_ASN_OP_OTHER
2765#undef DEFN_ASN_OP
2766
2767
2768inline sc_fxnum &
2769sc_fxnum::operator <<= (int b)
2770{
2771 SC_FXNUM_OBSERVER_READ_(*this)
2772 m_rep->lshift(b);
2773 cast();
2774 SC_FXNUM_OBSERVER_WRITE_(*this)
2775 return *this;
2776}
2777
2778inline sc_fxnum &
2779sc_fxnum::operator >>= (int b)
2780{
2781 SC_FXNUM_OBSERVER_READ_(*this)
2782 m_rep->rshift(b);
2783 cast();
2784 SC_FXNUM_OBSERVER_WRITE_(*this)
2785 return *this;
2786}
2787
2788// auto-increment and auto-decrement
2789inline const sc_fxval
2790sc_fxnum::operator ++ (int)
2791{
2792 sc_fxval c(*this);
2793 (*this) += 1;
2794 return c;
2795}
2796
2797inline const sc_fxval
2798sc_fxnum::operator -- (int)
2799{
2800 sc_fxval c(*this);
2801 (*this) -= 1;
2802 return c;
2803}
2804
2805inline sc_fxnum &
2806sc_fxnum::operator ++ ()
2807{
2808 (*this) += 1;
2809 return *this;
2810}
2811
2812inline sc_fxnum &
2813sc_fxnum::operator -- ()
2814{
2815 (*this) -= 1;
2816 return *this;
2817}
2818
2819// bit selection
2820inline const sc_fxnum_bitref
2821sc_fxnum::operator [] (int i) const
2822{
2823 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2824 return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2825 i - m_params.fwl());
2826}
2827
2828inline sc_fxnum_bitref
2829sc_fxnum::operator [] (int i)
2830{
2831 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2832 return sc_fxnum_bitref(*this, i - m_params.fwl());
2833}
2834
2835inline const sc_fxnum_bitref
2836sc_fxnum::bit(int i) const
2837{
2838 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2839 return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2840 i - m_params.fwl());
2841}
2842
2843inline sc_fxnum_bitref
2844sc_fxnum::bit(int i)
2845{
2846 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2847 return sc_fxnum_bitref(*this, i - m_params.fwl());
2848}
2849
2850// part selection
2851
2852inline const sc_fxnum_subref
2853sc_fxnum::operator () (int i, int j) const
2854{
2855 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2856 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2857
2858 return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2859 i - m_params.fwl(), j - m_params.fwl());
2860}
2861
2862inline sc_fxnum_subref
2863sc_fxnum::operator () (int i, int j)
2864{
2865 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2866 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2867
2868 return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2869}
2870
2871inline const sc_fxnum_subref
2872sc_fxnum::range(int i, int j) const
2873{
2874 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2875 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2876
2877 return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2878 i - m_params.fwl(), j - m_params.fwl());
2879}
2880
2881inline sc_fxnum_subref
2882sc_fxnum::range(int i, int j)
2883{
2884 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2885 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2886
2887 return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2888}
2889
2890
2891inline const sc_fxnum_subref
2892sc_fxnum::operator () () const
2893{
2894 return this->operator () (m_params.wl() - 1, 0);
2895}
2896
2897inline sc_fxnum_subref
2898sc_fxnum::operator () ()
2899{
2900 return this->operator () (m_params.wl() - 1, 0);
2901}
2902
2903inline const sc_fxnum_subref
2904sc_fxnum::range() const
2905{
2906 return this->range(m_params.wl() - 1, 0);
2907}
2908
2909inline sc_fxnum_subref
2910sc_fxnum::range()
2911{
2912 return this->range(m_params.wl() - 1, 0);
2913}
2914
2915// implicit conversion
2916inline sc_fxnum::operator double() const
2917{
2918 SC_FXNUM_OBSERVER_READ_(*this)
2919 return m_rep->to_double();
2920}
2921
2922// explicit conversion to primitive types
2923inline short
2924sc_fxnum::to_short() const
2925{
2926 SC_FXNUM_OBSERVER_READ_(*this)
2927 return static_cast<short>(m_rep->to_uint64());
2928}
2929
2930inline unsigned short
2931sc_fxnum::to_ushort() const
2932{
2933 SC_FXNUM_OBSERVER_READ_(*this)
2934 return static_cast<unsigned short>(m_rep->to_uint64());
2935}
2936
2937inline int
2938sc_fxnum::to_int() const
2939{
2940 SC_FXNUM_OBSERVER_READ_(*this)
2941 return static_cast<int>(m_rep->to_uint64());
2942}
2943
2944inline int64
2945sc_fxnum::to_int64() const
2946{
2947 SC_FXNUM_OBSERVER_READ_(*this)
2948 return static_cast<int64>(m_rep->to_uint64());
2949}
2950
2951inline unsigned int
2952sc_fxnum::to_uint() const
2953{
2954 SC_FXNUM_OBSERVER_READ_(*this)
2955 return static_cast<unsigned int>(m_rep->to_uint64());
2956}
2957
2958inline uint64
2959sc_fxnum::to_uint64() const
2960{
2961 SC_FXNUM_OBSERVER_READ_(*this)
2962 return m_rep->to_uint64();
2963}
2964
2965inline long
2966sc_fxnum::to_long() const
2967{
2968 SC_FXNUM_OBSERVER_READ_(*this)
2969 return static_cast<long>(m_rep->to_uint64());
2970}
2971
2972inline unsigned long
2973sc_fxnum::to_ulong() const
2974{
2975 SC_FXNUM_OBSERVER_READ_(*this)
2976 return static_cast<unsigned long>(m_rep->to_uint64());
2977}
2978
2979inline float
2980sc_fxnum::to_float() const
2981{
2982 SC_FXNUM_OBSERVER_READ_(*this)
2983 return static_cast<float>(m_rep->to_double());
2984}
2985
2986inline double
2987sc_fxnum::to_double() const
2988{
2989 SC_FXNUM_OBSERVER_READ_(*this)
2990 return m_rep->to_double();
2991}
2992
2993// query value
2994inline bool
2995sc_fxnum::is_neg() const
2996{
2997 SC_FXNUM_OBSERVER_READ_(*this)
2998 return m_rep->is_neg();
2999}
3000
3001inline bool
3002sc_fxnum::is_zero() const
3003{
3004 SC_FXNUM_OBSERVER_READ_(*this)
3005 return m_rep->is_zero();
3006}
3007
3008// internal use only;
3009inline bool
3010sc_fxnum::is_normal() const
3011{
3012 SC_FXNUM_OBSERVER_READ_(*this)
3013 return m_rep->is_normal();
3014}
3015
3016inline bool
3017sc_fxnum::quantization_flag() const
3018{
3019 return m_q_flag;
3020}
3021
3022inline bool
3023sc_fxnum::overflow_flag() const
3024{
3025 return m_o_flag;
3026}
3027
3028
3029inline const sc_fxval
3030sc_fxnum::value() const
3031{
3032 SC_FXNUM_OBSERVER_READ_(*this)
3033 return sc_fxval(new scfx_rep(*m_rep));
3034}
3035
3036// query parameters
3037inline int
3038sc_fxnum::wl() const
3039{
3040 return m_params.wl();
3041}
3042
3043inline int
3044sc_fxnum::iwl() const
3045{
3046 return m_params.iwl();
3047}
3048
3049inline sc_q_mode
3050sc_fxnum::q_mode() const
3051{
3052 return m_params.q_mode();
3053}
3054
3055inline sc_o_mode
3056sc_fxnum::o_mode() const
3057{
3058 return m_params.o_mode();
3059}
3060
3061inline int
3062sc_fxnum::n_bits() const
3063{
3064 return m_params.n_bits();
3065}
3066
3067inline const sc_fxtype_params &
3068sc_fxnum::type_params() const
3069{
3070 return m_params.type_params();
3071}
3072
3073inline const sc_fxcast_switch &
3074sc_fxnum::cast_switch() const
3075{
3076 return m_params.cast_switch();
3077}
3078
3079// internal use only;
3080inline void
3081sc_fxnum::observer_read() const
3082{
3083 SC_FXNUM_OBSERVER_READ_(*this);
3084}
3085
3086// internal use only;
3087inline bool
3088sc_fxnum::get_bit(int i) const
3089{
3090 return m_rep->get_bit(i);
3091}
3092
3093// protected methods and friend functions
3094inline bool
3095sc_fxnum::set_bit(int i, bool high)
3096{
3097 if (high)
3098 return m_rep->set(i, m_params);
3099 else
3100 return m_rep->clear(i, m_params);
3101}
3102
3103inline bool
3104sc_fxnum::get_slice(int i, int j, sc_bv_base &bv) const
3105{
3106 return m_rep->get_slice(i, j, m_params, bv);
3107}
3108
3109inline bool
3110sc_fxnum::set_slice(int i, int j, const sc_bv_base &bv)
3111{
3112 return m_rep->set_slice(i, j, m_params, bv);
3113}
3114
3115inline ::std::ostream &
3116operator << (::std::ostream &os, const sc_fxnum &a)
3117{
3118 a.print(os);
3119 return os;
3120}
3121
3122inline ::std::istream &
3123operator >> (::std::istream &is, sc_fxnum &a)
3124{
3125 a.scan(is);
3126 return is;
3127}
3128
3129
3130// ----------------------------------------------------------------------------
3131// CLASS : sc_fxnum_fast
3132//
3133// Base class for the fixed-point types; limited precision.
3134// ----------------------------------------------------------------------------
3135
3136inline sc_fxnum_fast_observer *
3137sc_fxnum_fast::observer() const
3138{
3139 return m_observer;
3140}
3141
3142
3143// constructors
3144inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxtype_params &type_params_,
3145 sc_enc enc_,
3146 const sc_fxcast_switch &cast_sw,
3147 sc_fxnum_fast_observer *observer_) :
3148 m_val(0.0), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3149 m_o_flag(false), m_observer(observer_)
3150{
3151 SC_FXNUM_FAST_OBSERVER_DEFAULT_
3152 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3153}
3154
3155inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxnum_fast &a,
3156 const sc_fxtype_params &type_params_,
3157 sc_enc enc_,
3158 const sc_fxcast_switch &cast_sw,
3159 sc_fxnum_fast_observer *observer_) :
3160 m_val(a.m_val), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3161 m_o_flag(false), m_observer(observer_)
3162{
3163 SC_FXNUM_FAST_OBSERVER_DEFAULT_
3164 SC_FXNUM_FAST_OBSERVER_READ_(a)
3165 cast();
3166 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3167 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3168}
3169
3170#define DEFN_CTOR_T(tp, arg) \
3171inline sc_fxnum_fast::sc_fxnum_fast( \
3172 tp a, const sc_fxtype_params &type_params_, sc_enc enc_, \
3173 const sc_fxcast_switch &cast_sw, \
3174 sc_fxnum_fast_observer *observer_) : \
3175 m_val(arg), m_params(type_params_, enc_, cast_sw), m_q_flag(false), \
3176 m_o_flag(false), m_observer(observer_) \
3177{ \
3178 SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
3179 cast(); \
3180 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \
3181 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3182}
3183
3184#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, static_cast<double>(a))
3185#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, sc_fxval_fast::from_string(a))
3186#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
3187
3188DEFN_CTOR_T_A(int)
3189DEFN_CTOR_T_A(unsigned int)
3190DEFN_CTOR_T_A(long)
3191DEFN_CTOR_T_A(unsigned long)
3192DEFN_CTOR_T_A(float)
3193DEFN_CTOR_T_A(double)
3194DEFN_CTOR_T_B(const char *)
3195DEFN_CTOR_T_C(const sc_fxval &)
3196DEFN_CTOR_T_C(const sc_fxval_fast &)
3197DEFN_CTOR_T_C(const sc_fxnum &)
3198
3199DEFN_CTOR_T_A(int64)
3200DEFN_CTOR_T_A(uint64)
3201DEFN_CTOR_T_C(const sc_int_base &)
3202DEFN_CTOR_T_C(const sc_uint_base &)
3203DEFN_CTOR_T_C(const sc_signed &)
3204DEFN_CTOR_T_C(const sc_unsigned &)
3205
3206#undef DEFN_CTOR_T
3207#undef DEFN_CTOR_T_A
3208#undef DEFN_CTOR_T_B
3209#undef DEFN_CTOR_T_C
3210#undef DEFN_CTOR_T_D
3211#undef DEFN_CTOR_T_E
3212
3213inline sc_fxnum_fast::~sc_fxnum_fast()
3214{
3215 SC_FXNUM_FAST_OBSERVER_DESTRUCT_(*this)
3216}
3217
3218// internal use only;
3219inline double
3220sc_fxnum_fast::get_val() const
3221{
3222 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3223 return m_val;
3224}
3225
3226// unary operators
3227inline const sc_fxval_fast
3228sc_fxnum_fast::operator - () const
3229{
3230 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3231 return sc_fxval_fast(- m_val);
3232}
3233
3234inline const sc_fxval_fast
3235sc_fxnum_fast::operator + () const
3236{
3237 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3238 return sc_fxval_fast(m_val);
3239}
3240
3241// unary functions
3242inline void
3243neg(sc_fxval_fast &c, const sc_fxnum_fast &a)
3244{
3245 SC_FXNUM_FAST_OBSERVER_READ_(a)
3246 c.set_val(- a.m_val);
3247}
3248
3249inline void
3250neg(sc_fxnum_fast &c, const sc_fxnum_fast &a)
3251{
3252 SC_FXNUM_FAST_OBSERVER_READ_(a)
3253 c.m_val = - a.m_val;
3254 c.cast();
3255 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3256}
3257
3258// binary operators
3259#define DEFN_BIN_OP_T(op, tp) \
3260inline const sc_fxval_fast \
3261operator op (const sc_fxnum_fast &a, tp b) \
3262{ \
3263 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3264 sc_fxval_fast tmp(b); \
3265 return sc_fxval_fast(a.m_val op tmp.get_val()); \
3266} \
3267 \
3268inline const sc_fxval_fast \
3269operator op (tp a, const sc_fxnum_fast &b) \
3270{ \
3271 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3272 sc_fxval_fast tmp(a); \
3273 return sc_fxval_fast(tmp.get_val() op b.m_val); \
3274}
3275
3276#define DEFN_BIN_OP_OTHER(op) \
3277DEFN_BIN_OP_T(op, int64) \
3278DEFN_BIN_OP_T(op, uint64) \
3279DEFN_BIN_OP_T(op, const sc_int_base &) \
3280DEFN_BIN_OP_T(op, const sc_uint_base &) \
3281DEFN_BIN_OP_T(op, const sc_signed &) \
3282DEFN_BIN_OP_T(op, const sc_unsigned &)
3283
3284#define DEFN_BIN_OP(op, dummy) \
3285inline const sc_fxval_fast \
3286operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3287{ \
3288 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3289 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3290 return sc_fxval_fast(a.m_val op b.m_val); \
3291} \
3292 \
3293inline const sc_fxval_fast \
3294operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3295{ \
3296 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3297 return sc_fxval_fast(a.m_val op b.get_val()); \
3298} \
3299 \
3300inline const sc_fxval_fast \
3301operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3302{ \
3303 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3304 return sc_fxval_fast(a.get_val() op b.m_val); \
3305} \
3306 \
3307DEFN_BIN_OP_T(op, int) \
3308DEFN_BIN_OP_T(op, unsigned int) \
3309DEFN_BIN_OP_T(op, long) \
3310DEFN_BIN_OP_T(op, unsigned long) \
3311DEFN_BIN_OP_T(op, float) \
3312DEFN_BIN_OP_T(op, double) \
3313DEFN_BIN_OP_T(op, const char *) \
3314DEFN_BIN_OP_OTHER(op)
3315
3316DEFN_BIN_OP(*, mult)
3317DEFN_BIN_OP(+, add)
3318DEFN_BIN_OP(-, sub)
3319//DEFN_BIN_OP(/, div)
3320inline const sc_fxval_fast
3321operator / (const sc_fxnum_fast &a, const sc_fxnum_fast &b)
3322{
3323 SC_FXNUM_FAST_OBSERVER_READ_(a)
3324 SC_FXNUM_FAST_OBSERVER_READ_(b)
3325 return sc_fxval_fast(a.m_val / b.m_val);
3326}
3327
3328inline const sc_fxval_fast
3329operator / (const sc_fxnum_fast &a, const sc_fxval_fast &b)
3330{
3331 SC_FXNUM_FAST_OBSERVER_READ_(a)
3332 return sc_fxval_fast(a.m_val / b.get_val());
3333}
3334
3335inline const sc_fxval_fast
3336operator / (const sc_fxval_fast &a, const sc_fxnum_fast &b)
3337{
3338 SC_FXNUM_FAST_OBSERVER_READ_(b)
3339 return sc_fxval_fast(a.get_val() / b.m_val);
3340}
3341
3342DEFN_BIN_OP_T(/, int)
3343DEFN_BIN_OP_T(/, unsigned int)
3344DEFN_BIN_OP_T(/, long)
3345DEFN_BIN_OP_T(/, unsigned long)
3346DEFN_BIN_OP_T(/, float)
3347DEFN_BIN_OP_T(/, double)
3348DEFN_BIN_OP_T(/, const char *)
3349//DEFN_BIN_OP_OTHER(/)
3350
3351DEFN_BIN_OP_T(/, int64)
3352DEFN_BIN_OP_T(/, uint64)
3353DEFN_BIN_OP_T(/, const sc_int_base &)
3354DEFN_BIN_OP_T(/, const sc_uint_base &)
3355DEFN_BIN_OP_T(/, const sc_signed &)
3356DEFN_BIN_OP_T(/, const sc_unsigned &)
3357
3358#undef DEFN_BIN_OP_T
3359#undef DEFN_BIN_OP_OTHER
3360#undef DEFN_BIN_OP
3361
3362inline const sc_fxval_fast
3363operator << (const sc_fxnum_fast &a, int b)
3364{
3365 SC_FXNUM_FAST_OBSERVER_READ_(a)
3366 return sc_fxval_fast(a.m_val *scfx_pow2(b));
3367}
3368
3369inline const sc_fxval_fast
3370operator >> (const sc_fxnum_fast &a, int b)
3371{
3372 SC_FXNUM_FAST_OBSERVER_READ_(a)
3373 return sc_fxval_fast(a.m_val *scfx_pow2(-b));
3374}
3375
3376// binary functions
3377#define DEFN_BIN_FNC_T(fnc, op, tp) \
3378inline void \
3379fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, tp b) \
3380{ \
3381 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3382 sc_fxval_fast tmp(b); \
3383 c.set_val(a.m_val op tmp.get_val()); \
3384} \
3385 \
3386inline void \
3387fnc (sc_fxval_fast &c, tp a, const sc_fxnum_fast &b) \
3388{ \
3389 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3390 sc_fxval_fast tmp(a); \
3391 c.set_val(tmp.get_val() op b.m_val); \
3392} \
3393 \
3394inline void \
3395fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, tp b) \
3396{ \
3397 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3398 sc_fxval_fast tmp(b); \
3399 c.m_val = a.m_val op tmp.get_val(); \
3400 c.cast(); \
3401 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3402} \
3403 \
3404inline void \
3405fnc (sc_fxnum_fast &c, tp a, const sc_fxnum_fast &b) \
3406{ \
3407 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3408 sc_fxval_fast tmp(a); \
3409 c.m_val = tmp.get_val() op b.m_val; \
3410 c.cast(); \
3411 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3412}
3413
3414#define DEFN_BIN_FNC_OTHER(fnc, op) \
3415DEFN_BIN_FNC_T(fnc, op, int64) \
3416DEFN_BIN_FNC_T(fnc, op, uint64) \
3417DEFN_BIN_FNC_T(fnc, op, const sc_int_base &) \
3418DEFN_BIN_FNC_T(fnc, op, const sc_uint_base &) \
3419DEFN_BIN_FNC_T(fnc, op, const sc_signed &) \
3420DEFN_BIN_FNC_T(fnc, op, const sc_unsigned &)
3421
3422#define DEFN_BIN_FNC(fnc, op) \
3423inline void \
3424fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3425{ \
3426 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3427 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3428 c.set_val(a.m_val op b.m_val); \
3429} \
3430 \
3431inline void \
3432fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3433{ \
3434 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3435 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3436 c.m_val = a.m_val op b.m_val; \
3437 c.cast(); \
3438 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3439} \
3440 \
3441inline void \
3442fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3443{ \
3444 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3445 c.set_val(a.m_val op b.get_val()); \
3446} \
3447 \
3448inline void \
3449fnc (sc_fxval_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3450{ \
3451 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3452 c.set_val(a.get_val() op b.m_val); \
3453} \
3454 \
3455inline void \
3456fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3457{ \
3458 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3459 c.m_val = a.m_val op b.get_val(); \
3460 c.cast(); \
3461 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3462} \
3463 \
3464inline void \
3465fnc (sc_fxnum_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3466{ \
3467 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3468 c.m_val = a.get_val() op b.m_val; \
3469 c.cast(); \
3470 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3471} \
3472 \
3473DEFN_BIN_FNC_T(fnc, op, int) \
3474DEFN_BIN_FNC_T(fnc, op, unsigned int) \
3475DEFN_BIN_FNC_T(fnc, op, long) \
3476DEFN_BIN_FNC_T(fnc, op, unsigned long) \
3477DEFN_BIN_FNC_T(fnc, op, float) \
3478DEFN_BIN_FNC_T(fnc, op, double) \
3479DEFN_BIN_FNC_T(fnc, op, const char *) \
3480DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
3481DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &) \
3482DEFN_BIN_FNC_OTHER(fnc, op)
3483
3484DEFN_BIN_FNC(mult, *)
3485DEFN_BIN_FNC(div, /)
3486DEFN_BIN_FNC(add, +)
3487DEFN_BIN_FNC(sub, -)
3488
3489#undef DEFN_BIN_FNC_T
3490#undef DEFN_BIN_FNC_OTHER
3491#undef DEFN_BIN_FNC
3492
3493inline void
3494lshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3495{
3496 SC_FXNUM_FAST_OBSERVER_READ_(a)
3497 c.set_val(a.m_val * scfx_pow2(b));
3498}
3499
3500inline void
3501rshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3502{
3503 SC_FXNUM_FAST_OBSERVER_READ_(a)
3504 c.set_val(a.m_val * scfx_pow2(-b));
3505}
3506
3507inline void
3508lshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3509{
3510 SC_FXNUM_FAST_OBSERVER_READ_(a)
3511 c.m_val = a.m_val * scfx_pow2(b);
3512 c.cast();
3513 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3514}
3515
3516inline void
3517rshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3518{
3519 SC_FXNUM_FAST_OBSERVER_READ_(a)
3520 c.m_val = a.m_val * scfx_pow2(-b);
3521 c.cast();
3522 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3523}
3524
3525// relational (including equality) operators
3526#define DEFN_REL_OP_T(op, tp) \
3527inline bool \
3528operator op (const sc_fxnum_fast &a, tp b) \
3529{ \
3530 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3531 sc_fxval_fast tmp(b); \
3532 return (a.m_val op tmp.get_val()); \
3533} \
3534 \
3535inline bool \
3536operator op (tp a, const sc_fxnum_fast &b) \
3537{ \
3538 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3539 sc_fxval_fast tmp(a); \
3540 return (tmp.get_val() op b.m_val); \
3541}
3542
3543#define DEFN_REL_OP_OTHER(op) \
3544DEFN_REL_OP_T(op, int64) \
3545DEFN_REL_OP_T(op, uint64) \
3546DEFN_REL_OP_T(op, const sc_int_base &) \
3547DEFN_REL_OP_T(op, const sc_uint_base &) \
3548DEFN_REL_OP_T(op, const sc_signed &) \
3549DEFN_REL_OP_T(op, const sc_unsigned &)
3550
3551#define DEFN_REL_OP(op) \
3552inline bool \
3553operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3554{ \
3555 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3556 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3557 return (a.m_val op b.m_val); \
3558} \
3559 \
3560inline bool \
3561operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3562{ \
3563 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3564 return (a.m_val op b.get_val()); \
3565} \
3566 \
3567inline bool \
3568operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3569{ \
3570 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3571 return (a.get_val() op b.m_val); \
3572} \
3573 \
3574DEFN_REL_OP_T(op, int) \
3575DEFN_REL_OP_T(op, unsigned int) \
3576DEFN_REL_OP_T(op, long) \
3577DEFN_REL_OP_T(op, unsigned long) \
3578DEFN_REL_OP_T(op, float) \
3579DEFN_REL_OP_T(op, double) \
3580DEFN_REL_OP_T(op, const char *) \
3581DEFN_REL_OP_OTHER(op)
3582
3583DEFN_REL_OP(<)
3584DEFN_REL_OP(<=)
3585DEFN_REL_OP(>)
3586DEFN_REL_OP(>=)
3587DEFN_REL_OP(==)
3588DEFN_REL_OP(!=)
3589
3590#undef DEFN_REL_OP_T
3591#undef DEFN_REL_OP_OTHER
3592#undef DEFN_REL_OP
3593
3594// assignment operators
3595
3596inline sc_fxnum_fast &
3597sc_fxnum_fast::operator = (const sc_fxnum_fast &a)
3598{
3599 if (&a != this) {
3600 SC_FXNUM_FAST_OBSERVER_READ_(a)
3601 m_val = a.m_val;
3602 cast();
3603 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3604 }
3605 return *this;
3606}
3607
3608inline sc_fxnum_fast &
3609sc_fxnum_fast::operator = (const sc_fxval_fast &a)
3610{
3611 m_val = a.get_val();
3612 cast();
3613 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3614 return *this;
3615}
3616
3617#define DEFN_ASN_OP_T(tp) \
3618inline sc_fxnum_fast & \
3619sc_fxnum_fast::operator = (tp a) \
3620{ \
3621 sc_fxval_fast tmp(a); \
3622 m_val = tmp.get_val(); \
3623 cast(); \
3624 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3625 return *this; \
3626}
3627
3628DEFN_ASN_OP_T(int)
3629DEFN_ASN_OP_T(unsigned int)
3630DEFN_ASN_OP_T(long)
3631DEFN_ASN_OP_T(unsigned long)
3632DEFN_ASN_OP_T(float)
3633DEFN_ASN_OP_T(double)
3634DEFN_ASN_OP_T(const char *)
3635DEFN_ASN_OP_T(const sc_fxval &)
3636DEFN_ASN_OP_T(const sc_fxnum &)
3637
3638DEFN_ASN_OP_T(int64)
3639DEFN_ASN_OP_T(uint64)
3640DEFN_ASN_OP_T(const sc_int_base &)
3641DEFN_ASN_OP_T(const sc_uint_base &)
3642DEFN_ASN_OP_T(const sc_signed &)
3643DEFN_ASN_OP_T(const sc_unsigned &)
3644
3645#undef DEFN_ASN_OP_T
3646
3647#define DEFN_ASN_OP_T(op, tp) \
3648inline sc_fxnum_fast & \
3649sc_fxnum_fast::operator op (tp b) \
3650{ \
3651 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3652 sc_fxval_fast tmp(b); \
3653 m_val op tmp.get_val(); \
3654 cast(); \
3655 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3656 return *this; \
3657}
3658
3659#define DEFN_ASN_OP_OTHER(op) \
3660DEFN_ASN_OP_T(op, int64) \
3661DEFN_ASN_OP_T(op, uint64) \
3662DEFN_ASN_OP_T(op, const sc_int_base &) \
3663DEFN_ASN_OP_T(op, const sc_uint_base &) \
3664DEFN_ASN_OP_T(op, const sc_signed &) \
3665DEFN_ASN_OP_T(op, const sc_unsigned &)
3666
3667#define DEFN_ASN_OP(op) \
3668inline sc_fxnum_fast & \
3669sc_fxnum_fast::operator op (const sc_fxnum_fast &b) \
3670{ \
3671 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3672 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3673 m_val op b.m_val; \
3674 cast(); \
3675 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3676 return *this; \
3677} \
3678 \
3679inline sc_fxnum_fast & \
3680sc_fxnum_fast::operator op (const sc_fxval_fast &b) \
3681{ \
3682 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3683 m_val op b.get_val(); \
3684 cast(); \
3685 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3686 return *this; \
3687} \
3688 \
3689DEFN_ASN_OP_T(op, int) \
3690DEFN_ASN_OP_T(op, unsigned int) \
3691DEFN_ASN_OP_T(op, long) \
3692DEFN_ASN_OP_T(op, unsigned long) \
3693DEFN_ASN_OP_T(op, float) \
3694DEFN_ASN_OP_T(op, double) \
3695DEFN_ASN_OP_T(op, const char *) \
3696DEFN_ASN_OP_T(op, const sc_fxval &) \
3697DEFN_ASN_OP_T(op, const sc_fxnum &) \
3698DEFN_ASN_OP_OTHER(op)
3699
3700DEFN_ASN_OP(*=)
3701DEFN_ASN_OP(/=)
3702DEFN_ASN_OP(+=)
3703DEFN_ASN_OP(-=)
3704
3705#undef DEFN_ASN_OP_T
3706#undef DEFN_ASN_OP_OTHER
3707#undef DEFN_ASN_OP
3708
3709inline sc_fxnum_fast &
3710sc_fxnum_fast::operator <<= (int b)
3711{
3712 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3713 m_val *= scfx_pow2(b);
3714 cast();
3715 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3716 return *this;
3717}
3718
3719inline sc_fxnum_fast &
3720sc_fxnum_fast::operator >>= (int b)
3721{
3722 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3723 m_val *= scfx_pow2(-b);
3724 cast();
3725 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3726 return *this;
3727}
3728
3729// auto-increment and auto-decrement
3730inline const sc_fxval_fast
3731sc_fxnum_fast::operator ++ (int)
3732{
3733 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3734 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3735 double c = m_val;
3736 m_val = m_val + 1;
3737 cast();
3738 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3739 return sc_fxval_fast(c);
3740}
3741
3742inline const sc_fxval_fast
3743sc_fxnum_fast::operator -- (int)
3744{
3745 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3746 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3747 double c = m_val;
3748 m_val = m_val - 1;
3749 cast();
3750 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3751 return sc_fxval_fast(c);
3752}
3753
3754inline sc_fxnum_fast &
3755sc_fxnum_fast::operator ++ ()
3756{
3757 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3758 m_val = m_val + 1;
3759 cast();
3760 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3761 return *this;
3762}
3763
3764inline sc_fxnum_fast &
3765sc_fxnum_fast::operator -- ()
3766{
3767 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3768 m_val = m_val - 1;
3769 cast();
3770 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3771 return *this;
3772}
3773
3774// bit selection
3775inline const sc_fxnum_fast_bitref
3776sc_fxnum_fast::operator [] (int i) const
3777{
3778 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3779 return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3780 i - m_params.fwl());
3781}
3782
3783inline sc_fxnum_fast_bitref
3784sc_fxnum_fast::operator [] (int i)
3785{
3786 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3787 return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3788}
3789
3790inline const sc_fxnum_fast_bitref
3791sc_fxnum_fast::bit(int i) const
3792{
3793 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3794 return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3795 i - m_params.fwl());
3796}
3797
3798inline sc_fxnum_fast_bitref
3799sc_fxnum_fast::bit(int i)
3800{
3801 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3802 return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3803}
3804
3805// part selection
3806inline const sc_fxnum_fast_subref
3807sc_fxnum_fast::operator () (int i, int j) const
3808{
3809 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3810 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3811
3812 return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3813 i - m_params.fwl(), j - m_params.fwl());
3814}
3815
3816inline sc_fxnum_fast_subref
3817sc_fxnum_fast::operator () (int i, int j)
3818{
3819 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3820 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3821
3822 return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3823}
3824
3825inline const sc_fxnum_fast_subref
3826sc_fxnum_fast::range(int i, int j) const
3827{
3828 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3829 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3830
3831 return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3832 i - m_params.fwl(), j - m_params.fwl());
3833}
3834
3835inline sc_fxnum_fast_subref
3836sc_fxnum_fast::range(int i, int j)
3837{
3838 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3839 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3840
3841 return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3842}
3843
3844inline const sc_fxnum_fast_subref
3845sc_fxnum_fast::operator () () const
3846{
3847 return this->operator () (m_params.wl() - 1, 0);
3848}
3849
3850inline sc_fxnum_fast_subref
3851sc_fxnum_fast::operator () ()
3852{
3853 return this->operator () (m_params.wl() - 1, 0);
3854}
3855
3856inline const sc_fxnum_fast_subref
3857sc_fxnum_fast::range() const
3858{
3859 return this->range(m_params.wl() - 1, 0);
3860}
3861
3862inline sc_fxnum_fast_subref
3863sc_fxnum_fast::range()
3864{
3865 return this->range(m_params.wl() - 1, 0);
3866}
3867
3868// implicit conversion
3869inline sc_fxnum_fast::operator double() const
3870{
3871 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3872 return m_val;
3873}
3874
3875// explicit conversion to primitive types
3876inline short
3877sc_fxnum_fast::to_short() const
3878{
3879 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3880 return static_cast<short>(to_uint64());
3881}
3882
3883inline unsigned short
3884sc_fxnum_fast::to_ushort() const
3885{
3886 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3887 return static_cast<unsigned short>(to_uint64());
3888}
3889
3890inline int
3891sc_fxnum_fast::to_int() const
3892{
3893 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3894 return static_cast<int>(to_uint64());
3895}
3896
3897inline int64
3898sc_fxnum_fast::to_int64() const
3899{
3900 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3901 return static_cast<int64>(to_uint64());
3902}
3903
3904inline unsigned int
3905sc_fxnum_fast::to_uint() const
3906{
3907 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3908 return static_cast<unsigned int>(to_uint64());
3909}
3910
3911inline uint64
3912sc_fxnum_fast::to_uint64() const
3913{
3914 // SC_FXNUM_FAST_OBSERVER_READ_ in is_normal
3915 if (!is_normal()) {
3916 return 0;
3917 }
3918
3919 int exponent;
3920 double mantissa_dbl = frexp(m_val, &exponent);
3921
3922 uint64 mantissa = static_cast<uint64>(fabs(mantissa_dbl) *
3923 (UINT64_ONE << 53));
3924 exponent -= 53;
3925
3926 if (!(-64 < exponent && exponent < 64)) {
3927 return 0;
3928 }
3929
3930 mantissa = exponent >= 0 ? mantissa << exponent : mantissa >> -exponent;
3931 return mantissa_dbl >= 0 ? mantissa : -mantissa;
3932}
3933
3934inline long
3935sc_fxnum_fast::to_long() const
3936{
3937 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3938 return static_cast<long>(to_uint64());
3939}
3940
3941inline unsigned long
3942sc_fxnum_fast::to_ulong() const
3943{
3944 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3945 return static_cast<unsigned long>(to_uint64());
3946}
3947
3948inline float
3949sc_fxnum_fast::to_float() const
3950{
3951 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3952 return static_cast<float>(m_val);
3953}
3954
3955inline double
3956sc_fxnum_fast::to_double() const
3957{
3958 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3959 return m_val;
3960}
3961
3962// query value
3963inline bool
3964sc_fxnum_fast::is_neg() const
3965{
3966 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3967 scfx_ieee_double id(m_val);
3968 return (id.negative() != 0);
3969}
3970
3971inline bool
3972sc_fxnum_fast::is_zero() const
3973{
3974 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3975 scfx_ieee_double id(m_val);
3976 return id.is_zero();
3977}
3978
3979// internal use only;
3980inline bool
3981sc_fxnum_fast::is_normal() const
3982{
3983 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3984 scfx_ieee_double id(m_val);
3985 return (id.is_normal() || id.is_subnormal() || id.is_zero());
3986}
3987
3988inline bool
3989sc_fxnum_fast::quantization_flag() const
3990{
3991 return m_q_flag;
3992}
3993
3994inline bool
3995sc_fxnum_fast::overflow_flag() const
3996{
3997 return m_o_flag;
3998}
3999
4000inline const sc_fxval_fast
4001sc_fxnum_fast::value() const
4002{
4003 SC_FXNUM_FAST_OBSERVER_READ_(*this)
4004 return sc_fxval_fast(m_val);
4005}
4006
4007// query parameters
4008inline int
4009sc_fxnum_fast::wl() const
4010{
4011 return m_params.wl();
4012}
4013
4014inline int
4015sc_fxnum_fast::iwl() const
4016{
4017 return m_params.iwl();
4018}
4019
4020inline sc_q_mode
4021sc_fxnum_fast::q_mode() const
4022{
4023 return m_params.q_mode();
4024}
4025
4026inline sc_o_mode
4027sc_fxnum_fast::o_mode() const
4028{
4029 return m_params.o_mode();
4030}
4031
4032inline int
4033sc_fxnum_fast::n_bits() const
4034{
4035 return m_params.n_bits();
4036}
4037
4038inline const sc_fxtype_params &
4039sc_fxnum_fast::type_params() const
4040{
4041 return m_params.type_params();
4042}
4043
4044inline const sc_fxcast_switch &
4045sc_fxnum_fast::cast_switch() const
4046{
4047 return m_params.cast_switch();
4048}
4049
4050// internal use only;
4051inline void
4052sc_fxnum_fast::observer_read() const
4053{
4054 SC_FXNUM_FAST_OBSERVER_READ_(*this);
4055}
4056
4057inline ::std::ostream &
4058operator << (::std::ostream &os, const sc_fxnum_fast &a)
4059{
4060 a.print(os);
4061 return os;
4062}
4063
4064inline ::std::istream &
4065operator >> (::std::istream &is, sc_fxnum_fast &a)
4066{
4067 a.scan(is);
4068 return is;
4069}
4070
4071
4072// ----------------------------------------------------------------------------
4073// CLASS : sc_fxval
4074//
4075// Fixed-point value type; arbitrary precision.
4076// ----------------------------------------------------------------------------
4077
4078// public constructors
4079inline sc_fxval::sc_fxval(const sc_fxnum &a, sc_fxval_observer *observer_) :
4080 m_rep(new scfx_rep(*a.get_rep())), m_observer(observer_)
4081{
4082 SC_FXVAL_OBSERVER_DEFAULT_
4083 SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4084 SC_FXVAL_OBSERVER_WRITE_(*this)
4085}
4086
4087inline sc_fxval::sc_fxval(const sc_fxnum_fast &a,
4088 sc_fxval_observer *observer_) :
4089 m_rep(new scfx_rep(a.to_double())), m_observer(observer_)
4090{
4091 SC_FXVAL_OBSERVER_DEFAULT_
4092 SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4093 SC_FXVAL_OBSERVER_WRITE_(*this)
4094}
4095
4096// binary operators
4097#define DEFN_BIN_OP_T(op, fnc, tp) \
4098inline const sc_fxval \
4099operator op (const sc_fxval &a, tp b) \
4100{ \
4101 SC_FXVAL_OBSERVER_READ_(a) \
4102 sc_fxval tmp(b); \
4103 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep)); \
4104} \
4105 \
4106inline const sc_fxval \
4107operator op (tp a, const sc_fxval &b) \
4108{ \
4109 SC_FXVAL_OBSERVER_READ_(b) \
4110 sc_fxval tmp(a); \
4111 return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep)); \
4112}
4113
4114#define DEFN_BIN_OP(op, fnc) \
4115DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &)
4116
4117DEFN_BIN_OP(*, mult)
4118DEFN_BIN_OP(+, add)
4119DEFN_BIN_OP(-, sub)
4120//DEFN_BIN_OP(/, div)
4121DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
4122
4123#undef DEFN_BIN_OP_T
4124#undef DEFN_BIN_OP
4125
4126
4127// binary functions
4128#define DEFN_BIN_FNC_T(fnc, tp) \
4129inline void \
4130fnc (sc_fxval &c, const sc_fxval &a, tp b) \
4131{ \
4132 SC_FXVAL_OBSERVER_READ_(a) \
4133 sc_fxval tmp(b); \
4134 delete c.m_rep; \
4135 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep); \
4136 SC_FXVAL_OBSERVER_WRITE_(c) \
4137} \
4138 \
4139inline void \
4140fnc (sc_fxval &c, tp a, const sc_fxval &b) \
4141{ \
4142 SC_FXVAL_OBSERVER_READ_(b) \
4143 sc_fxval tmp(a); \
4144 delete c.m_rep; \
4145 c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep); \
4146 SC_FXVAL_OBSERVER_WRITE_(c) \
4147}
4148
4149#define DEFN_BIN_FNC(fnc) \
4150DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &)
4151
4152DEFN_BIN_FNC(mult)
4153DEFN_BIN_FNC(div)
4154DEFN_BIN_FNC(add)
4155DEFN_BIN_FNC(sub)
4156
4157#undef DEFN_BIN_FNC_T
4158#undef DEFN_BIN_FNC
4159
4160
4161// relational (including equality) operators
4162#define DEFN_REL_OP_T(op, ret, tp) \
4163inline bool \
4164operator op (const sc_fxval &a, tp b) \
4165{ \
4166 SC_FXVAL_OBSERVER_READ_(a) \
4167 sc_fxval tmp(b); \
4168 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.m_rep); \
4169 return (ret); \
4170} \
4171 \
4172inline bool \
4173operator op (tp a, const sc_fxval &b) \
4174{ \
4175 SC_FXVAL_OBSERVER_READ_(b) \
4176 sc_fxval tmp(a); \
4177 int result = sc_dt::cmp_scfx_rep(*tmp.m_rep, *b.m_rep); \
4178 return (ret); \
4179}
4180
4181#define DEFN_REL_OP(op, ret) \
4182DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &)
4183
4184DEFN_REL_OP(<, result < 0)
4185DEFN_REL_OP(<=, result <= 0)
4186DEFN_REL_OP(>, result > 0 && result != 2)
4187DEFN_REL_OP(>=, result >= 0 && result != 2)
4188DEFN_REL_OP(==, result == 0)
4189DEFN_REL_OP(!=, result != 0)
4190
4191#undef DEFN_REL_OP_T
4192#undef DEFN_REL_OP
4193
4194// assignment operators
4195inline sc_fxval &
4196sc_fxval::operator = (const sc_fxnum &a)
4197{
4198 *m_rep = *a.get_rep();
4199 SC_FXVAL_OBSERVER_WRITE_(*this)
4200 return *this;
4201}
4202
4203#define DEFN_ASN_OP_T(tp) \
4204inline sc_fxval & \
4205sc_fxval::operator = (tp b) \
4206{ \
4207 sc_fxval tmp(b); \
4208 *m_rep = *tmp.m_rep; \
4209 SC_FXVAL_OBSERVER_WRITE_(*this) \
4210 return *this; \
4211}
4212
4213DEFN_ASN_OP_T(const sc_fxnum_fast &)
4214
4215#undef DEFN_ASN_OP_T
4216
4217#define DEFN_ASN_OP_T(op, fnc, tp) \
4218inline sc_fxval & \
4219sc_fxval::operator op (tp b) \
4220{ \
4221 SC_FXVAL_OBSERVER_READ_(*this) \
4222 sc_fxval tmp(b); \
4223 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.m_rep); \
4224 delete m_rep; \
4225 m_rep = new_rep; \
4226 SC_FXVAL_OBSERVER_WRITE_(*this) \
4227 return *this; \
4228}
4229
4230#define DEFN_ASN_OP(op, fnc) \
4231inline sc_fxval & \
4232sc_fxval::operator op (const sc_fxnum &b) \
4233{ \
4234 SC_FXVAL_OBSERVER_READ_(*this) \
4235 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
4236 delete m_rep; \
4237 m_rep = new_rep; \
4238 SC_FXVAL_OBSERVER_WRITE_(*this) \
4239 return *this; \
4240} \
4241 \
4242DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &)
4243
4244DEFN_ASN_OP(*=, mult)
4245DEFN_ASN_OP(/=, div)
4246DEFN_ASN_OP(+=, add)
4247DEFN_ASN_OP(-=, sub)
4248
4249#undef DEFN_ASN_OP_T
4250#undef DEFN_ASN_OP
4251
4252
4253// ----------------------------------------------------------------------------
4254// CLASS : sc_fxval_fast
4255//
4256// Fixed-point value types; limited precision.
4257// ----------------------------------------------------------------------------
4258
4259// public constructors
4260
4261inline
4262sc_fxval_fast::sc_fxval_fast(const sc_fxnum &a,
4263 sc_fxval_fast_observer *observer_) :
4264 m_val(a.to_double()), m_observer(observer_)
4265{
4266 SC_FXVAL_FAST_OBSERVER_DEFAULT_
4267 SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4268 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4269}
4270
4271inline sc_fxval_fast::sc_fxval_fast(const sc_fxnum_fast &a,
4272 sc_fxval_fast_observer *observer_) :
4273 m_val(a.get_val()), m_observer(observer_)
4274{
4275 SC_FXVAL_FAST_OBSERVER_DEFAULT_
4276 SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4277 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4278}
4279
4280
4281// binary functions
4282#define DEFN_BIN_FNC_T(fnc, op, tp) \
4283inline void \
4284fnc (sc_fxval_fast &c, const sc_fxval_fast &a, tp b) \
4285{ \
4286 SC_FXVAL_FAST_OBSERVER_READ_(a) \
4287 sc_fxval_fast tmp(b); \
4288 c.m_val = a.m_val op tmp.m_val; \
4289 SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4290} \
4291 \
4292inline void \
4293fnc (sc_fxval_fast &c, tp a, const sc_fxval_fast &b) \
4294{ \
4295 SC_FXVAL_FAST_OBSERVER_READ_(b) \
4296 sc_fxval_fast tmp(a); \
4297 c.m_val = tmp.m_val op b.m_val; \
4298 SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4299}
4300
4301#define DEFN_BIN_FNC(fnc, op) \
4302DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
4303DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &)
4304
4305DEFN_BIN_FNC(mult, *)
4306DEFN_BIN_FNC(div, /)
4307DEFN_BIN_FNC(add, +)
4308DEFN_BIN_FNC(sub, -)
4309
4310#undef DEFN_BIN_FNC_T
4311#undef DEFN_BIN_FNC
4312
4313
4314// assignment operators
4315inline sc_fxval_fast &
4316sc_fxval_fast::operator = (const sc_fxnum_fast &a)
4317{
4318 m_val = a.get_val();
4319 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4320 return *this;
4321}
4322
4323#define DEFN_ASN_OP_T(tp) \
4324inline sc_fxval_fast & \
4325sc_fxval_fast::operator = (tp a) \
4326{ \
4327 sc_fxval_fast tmp(a); \
4328 m_val = tmp.m_val; \
4329 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4330 return *this; \
4331}
4332
4333DEFN_ASN_OP_T(const sc_fxnum &)
4334
4335#undef DEFN_ASN_OP_T
4336
4337#define DEFN_ASN_OP_T(op, tp) \
4338inline sc_fxval_fast & \
4339sc_fxval_fast::operator op (tp b) \
4340{ \
4341 SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4342 sc_fxval_fast tmp(b); \
4343 m_val op tmp.m_val; \
4344 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4345 return *this; \
4346}
4347
4348#define DEFN_ASN_OP(op) \
4349inline sc_fxval_fast & \
4350sc_fxval_fast::operator op (const sc_fxnum_fast &b) \
4351{ \
4352 SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4353 m_val op b.get_val(); \
4354 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4355 return *this; \
4356} \
4357 \
4358DEFN_ASN_OP_T(op, const sc_fxnum &)
4359
4360DEFN_ASN_OP(*=)
4361DEFN_ASN_OP(/=)
4362DEFN_ASN_OP(+=)
4363DEFN_ASN_OP(-=)
4364
4365#undef DEFN_ASN_OP_T
4366#undef DEFN_ASN_OP
4367
4368} // namespace sc_dt
4369
4370#endif // __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
854
855 protected:
856 sc_fxnum_fast_observer *observer() const;
857
858 void cast();
859
860 // constructors
861 sc_fxnum_fast(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
862 sc_fxnum_fast_observer *);
863
864#define DECL_CTOR_T(tp) \
865 sc_fxnum_fast(tp, const sc_fxtype_params &, sc_enc, \
866 const sc_fxcast_switch &, sc_fxnum_fast_observer *);
867
868 DECL_CTOR_T(int)
869 DECL_CTOR_T(unsigned int)
870 DECL_CTOR_T(long)
871 DECL_CTOR_T(unsigned long)
872 DECL_CTOR_T(float)
873 DECL_CTOR_T(double)
874 DECL_CTOR_T(const char *)
875 DECL_CTOR_T(const sc_fxval &)
876 DECL_CTOR_T(const sc_fxval_fast &)
877 DECL_CTOR_T(const sc_fxnum &)
878 DECL_CTOR_T(const sc_fxnum_fast &)
879
880 DECL_CTOR_T(int64)
881 DECL_CTOR_T(uint64)
882 DECL_CTOR_T(const sc_int_base &)
883 DECL_CTOR_T(const sc_uint_base &)
884 DECL_CTOR_T(const sc_signed &)
885 DECL_CTOR_T(const sc_unsigned &)
886
887#undef DECL_CTOR_T
888 ~sc_fxnum_fast();
889
890 // internal use only;
891 double get_val() const;
892
893 public:
894 // unary operators
895 const sc_fxval_fast operator - () const;
896 const sc_fxval_fast operator + () const;
897
898 // unary functions
899 friend void neg(sc_fxval_fast &, const sc_fxnum_fast &);
900 friend void neg(sc_fxnum_fast &, const sc_fxnum_fast &);
901
902
903 // binary operators
904#define DECL_BIN_OP_T(op, tp) \
905 friend const sc_fxval_fast operator op (const sc_fxnum_fast &, tp); \
906 friend const sc_fxval_fast operator op (tp, const sc_fxnum_fast &);
907
908#define DECL_BIN_OP_OTHER(op) \
909 DECL_BIN_OP_T(op, int64) \
910 DECL_BIN_OP_T(op, uint64) \
911 DECL_BIN_OP_T(op, const sc_int_base &) \
912 DECL_BIN_OP_T(op, const sc_uint_base &) \
913 DECL_BIN_OP_T(op, const sc_signed &) \
914 DECL_BIN_OP_T(op, const sc_unsigned &)
915
916#define DECL_BIN_OP(op, dummy) \
917 friend const sc_fxval_fast operator op (const sc_fxnum_fast &, \
918 const sc_fxnum_fast &); \
919 DECL_BIN_OP_T(op, int) \
920 DECL_BIN_OP_T(op, unsigned int) \
921 DECL_BIN_OP_T(op, long) \
922 DECL_BIN_OP_T(op, unsigned long) \
923 DECL_BIN_OP_T(op, float) \
924 DECL_BIN_OP_T(op, double) \
925 DECL_BIN_OP_T(op, const char *) \
926 DECL_BIN_OP_T(op, const sc_fxval_fast &) \
927 DECL_BIN_OP_OTHER(op)
928
929 DECL_BIN_OP(*, mult)
930 DECL_BIN_OP(+, add)
931 DECL_BIN_OP(-, sub)
932// DECL_BIN_OP(/, div)
933 friend const sc_fxval_fast operator / (const sc_fxnum_fast &,
934 const sc_fxnum_fast &);
935 DECL_BIN_OP_T(/, int)
936 DECL_BIN_OP_T(/, unsigned int)
937 DECL_BIN_OP_T(/, long)
938 DECL_BIN_OP_T(/, unsigned long)
939 DECL_BIN_OP_T(/, float)
940 DECL_BIN_OP_T(/, double)
941 DECL_BIN_OP_T(/, const char *)
942 DECL_BIN_OP_T(/, const sc_fxval_fast &)
943// DECL_BIN_OP_OTHER(op)
944
945 DECL_BIN_OP_T(/, int64) \
946 DECL_BIN_OP_T(/, uint64) \
947 DECL_BIN_OP_T(/, const sc_int_base &) \
948 DECL_BIN_OP_T(/, const sc_uint_base &) \
949 DECL_BIN_OP_T(/, const sc_signed &) \
950 DECL_BIN_OP_T(/, const sc_unsigned &)
951
952#undef DECL_BIN_OP_T
953#undef DECL_BIN_OP_OTHER
954#undef DECL_BIN_OP
955
956 friend const sc_fxval_fast operator << (const sc_fxnum_fast &, int);
957 friend const sc_fxval_fast operator >> (const sc_fxnum_fast &, int);
958
959 // binary functions
960#define DECL_BIN_FNC_T(fnc, tp) \
961 friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, tp); \
962 friend void fnc (sc_fxval_fast &, tp, const sc_fxnum_fast &); \
963 friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, tp); \
964 friend void fnc (sc_fxnum_fast &, tp, const sc_fxnum_fast &);
965
966#define DECL_BIN_FNC_OTHER(fnc) \
967 DECL_BIN_FNC_T(fnc, int64) \
968 DECL_BIN_FNC_T(fnc, uint64) \
969 DECL_BIN_FNC_T(fnc, const sc_int_base &) \
970 DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
971 DECL_BIN_FNC_T(fnc, const sc_signed &) \
972 DECL_BIN_FNC_T(fnc, const sc_unsigned &)
973
974#define DECL_BIN_FNC(fnc) \
975 friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, \
976 const sc_fxnum_fast &); \
977 friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, \
978 const sc_fxnum_fast &); \
979 DECL_BIN_FNC_T(fnc, int) \
980 DECL_BIN_FNC_T(fnc, unsigned int) \
981 DECL_BIN_FNC_T(fnc, long) \
982 DECL_BIN_FNC_T(fnc, unsigned long) \
983 DECL_BIN_FNC_T(fnc, float) \
984 DECL_BIN_FNC_T(fnc, double) \
985 DECL_BIN_FNC_T(fnc, const char *) \
986 DECL_BIN_FNC_T(fnc, const sc_fxval &) \
987 DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
988 DECL_BIN_FNC_T(fnc, const sc_fxnum &) \
989 DECL_BIN_FNC_OTHER(fnc)
990
991 DECL_BIN_FNC(mult)
992 DECL_BIN_FNC(div)
993 DECL_BIN_FNC(add)
994 DECL_BIN_FNC(sub)
995
996#undef DECL_BIN_FNC_T
997#undef DECL_BIN_FNC_OTHER
998#undef DECL_BIN_FNC
999
1000 friend void lshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1001 friend void rshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1002 friend void lshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1003 friend void rshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1004
1005 // relational (including equality) operators
1006#define DECL_REL_OP_T(op, tp) \
1007 friend bool operator op (const sc_fxnum_fast &, tp); \
1008 friend bool operator op (tp, const sc_fxnum_fast &);
1009
1010#define DECL_REL_OP_OTHER(op) \
1011 DECL_REL_OP_T(op, int64) \
1012 DECL_REL_OP_T(op, uint64) \
1013 DECL_REL_OP_T(op, const sc_int_base &) \
1014 DECL_REL_OP_T(op, const sc_uint_base &) \
1015 DECL_REL_OP_T(op, const sc_signed &) \
1016 DECL_REL_OP_T(op, const sc_unsigned &)
1017
1018#define DECL_REL_OP(op) \
1019 friend bool operator op (const sc_fxnum_fast &, const sc_fxnum_fast &); \
1020 DECL_REL_OP_T(op, int) \
1021 DECL_REL_OP_T(op, unsigned int) \
1022 DECL_REL_OP_T(op, long) \
1023 DECL_REL_OP_T(op, unsigned long) \
1024 DECL_REL_OP_T(op, float) \
1025 DECL_REL_OP_T(op, double) \
1026 DECL_REL_OP_T(op, const char *) \
1027 DECL_REL_OP_T(op, const sc_fxval_fast &) \
1028 DECL_REL_OP_OTHER(op)
1029
1030 DECL_REL_OP(<)
1031 DECL_REL_OP(<=)
1032 DECL_REL_OP(>)
1033 DECL_REL_OP(>=)
1034 DECL_REL_OP(==)
1035 DECL_REL_OP(!=)
1036
1037#undef DECL_REL_OP_T
1038#undef DECL_REL_OP_OTHER
1039#undef DECL_REL_OP
1040
1041 // assignment operators
1042#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast &operator op(tp);
1043
1044#define DECL_ASN_OP_OTHER(op) \
1045 DECL_ASN_OP_T(op, int64) \
1046 DECL_ASN_OP_T(op, uint64) \
1047 DECL_ASN_OP_T(op, const sc_int_base &) \
1048 DECL_ASN_OP_T(op, const sc_uint_base &) \
1049 DECL_ASN_OP_T(op, const sc_signed &) \
1050 DECL_ASN_OP_T(op, const sc_unsigned &)
1051
1052#define DECL_ASN_OP(op) \
1053 DECL_ASN_OP_T(op, int) \
1054 DECL_ASN_OP_T(op, unsigned int) \
1055 DECL_ASN_OP_T(op, long) \
1056 DECL_ASN_OP_T(op, unsigned long) \
1057 DECL_ASN_OP_T(op, float) \
1058 DECL_ASN_OP_T(op, double) \
1059 DECL_ASN_OP_T(op, const char *) \
1060 DECL_ASN_OP_T(op, const sc_fxval &) \
1061 DECL_ASN_OP_T(op, const sc_fxval_fast &) \
1062 DECL_ASN_OP_T(op, const sc_fxnum &) \
1063 DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
1064 DECL_ASN_OP_OTHER(op)
1065
1066 DECL_ASN_OP(=)
1067
1068 DECL_ASN_OP(*=)
1069 DECL_ASN_OP(/=)
1070 DECL_ASN_OP(+=)
1071 DECL_ASN_OP(-=)
1072
1073 DECL_ASN_OP_T(<<=, int)
1074 DECL_ASN_OP_T(>>=, int)
1075
1076#undef DECL_ASN_OP_T
1077#undef DECL_ASN_OP_OTHER
1078#undef DECL_ASN_OP
1079
1080 // auto-increment and auto-decrement
1081 const sc_fxval_fast operator ++ (int);
1082 const sc_fxval_fast operator -- (int);
1083
1084 sc_fxnum_fast &operator ++ ();
1085 sc_fxnum_fast &operator -- ();
1086
1087 // bit selection
1088 const sc_fxnum_fast_bitref operator [] (int) const;
1089 sc_fxnum_fast_bitref operator [] (int);
1090
1091 const sc_fxnum_fast_bitref bit(int) const;
1092 sc_fxnum_fast_bitref bit(int);
1093
1094 // part selection
1095 const sc_fxnum_fast_subref operator () (int, int) const;
1096 sc_fxnum_fast_subref operator () (int, int);
1097
1098 const sc_fxnum_fast_subref range(int, int) const;
1099 sc_fxnum_fast_subref range(int, int);
1100
1101
1102 const sc_fxnum_fast_subref operator () () const;
1103 sc_fxnum_fast_subref operator () ();
1104
1105 const sc_fxnum_fast_subref range() const;
1106 sc_fxnum_fast_subref range();
1107
1108 // implicit conversion
1109 operator double() const; // necessary evil!
1110
1111 // explicit conversion to primitive types
1112 short to_short() const;
1113 unsigned short to_ushort() const;
1114 int to_int() const;
1115 unsigned int to_uint() const;
1116 long to_long() const;
1117 unsigned long to_ulong() const;
1118 int64 to_int64() const;
1119 uint64 to_uint64() const;
1120 float to_float() const;
1121 double to_double() const;
1122
1123 // explicit conversion to character string
1124 const std::string to_string() const;
1125 const std::string to_string(sc_numrep) const;
1126 const std::string to_string(sc_numrep, bool) const;
1127 const std::string to_string(sc_fmt) const;
1128 const std::string to_string(sc_numrep, sc_fmt) const;
1129 const std::string to_string(sc_numrep, bool, sc_fmt) const;
1130
1131 const std::string to_dec() const;
1132 const std::string to_bin() const;
1133 const std::string to_oct() const;
1134 const std::string to_hex() const;
1135
1136 // query value
1137 bool is_neg() const;
1138 bool is_zero() const;
1139
1140 // internal use only;
1141 bool is_normal() const;
1142
1143 bool quantization_flag() const;
1144 bool overflow_flag() const;
1145
1146 const sc_fxval_fast value() const;
1147
1148 // query parameters
1149 int wl() const;
1150 int iwl() const;
1151 sc_q_mode q_mode() const;
1152 sc_o_mode o_mode() const;
1153 int n_bits() const;
1154
1155 const sc_fxtype_params &type_params() const;
1156
1157 const sc_fxcast_switch &cast_switch() const;
1158
1159 // print or dump content
1160 void print(::std::ostream & =::std::cout) const;
1161 void scan(::std::istream & =::std::cin);
1162 void dump(::std::ostream & =::std::cout) const;
1163
1164 // internal use only;
1165 void observer_read() const;
1166
1167 // internal use only;
1168 bool get_bit(int) const;
1169
1170 protected:
1171 bool set_bit(int, bool);
1172
1173 bool get_slice(int, int, sc_bv_base &) const;
1174 bool set_slice(int, int, const sc_bv_base &);
1175
1176 sc_fxnum_fast_observer *lock_observer() const;
1177 void unlock_observer(sc_fxnum_fast_observer *) const;
1178
1179 private:
1180 double m_val;
1181
1182 scfx_params m_params;
1183 bool m_q_flag;
1184 bool m_o_flag;
1185
1186 mutable sc_fxnum_fast_observer *m_observer;
1187
1188 private:
1189 // Disabled
1190 sc_fxnum_fast();
1191 sc_fxnum_fast(const sc_fxnum_fast &);
1192};
1193
1194
1195// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1196
1197// ----------------------------------------------------------------------------
1198// CLASS : sc_fxnum_bitref
1199//
1200// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
1201// ----------------------------------------------------------------------------
1202
1203// constructor
1204
1205inline
1206sc_fxnum_bitref::sc_fxnum_bitref(sc_fxnum &num_, int idx_) :
1207 m_num(num_), m_idx(idx_)
1208{}
1209
1210// copy constructor
1211inline sc_fxnum_bitref::sc_fxnum_bitref(const sc_fxnum_bitref &a) :
1212 m_num(a.m_num), m_idx(a.m_idx)
1213{}
1214
1215// assignment operators
1216inline sc_fxnum_bitref &
1217sc_fxnum_bitref::operator = (const sc_fxnum_bitref &a)
1218{
1219 if (&a != this) {
1220 SC_FXNUM_OBSERVER_READ_(a.m_num)
1221 set(a.get());
1222 SC_FXNUM_OBSERVER_WRITE_(m_num)
1223 }
1224 return *this;
1225}
1226
1227inline sc_fxnum_bitref &
1228sc_fxnum_bitref::operator = (const sc_fxnum_fast_bitref &a)
1229{
1230 SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1231 set(a.get());
1232 SC_FXNUM_OBSERVER_WRITE_(m_num)
1233 return *this;
1234}
1235
1236inline sc_fxnum_bitref &
1237sc_fxnum_bitref::operator = (const sc_bit &a)
1238{
1239 set(static_cast<bool>(a));
1240 SC_FXNUM_OBSERVER_WRITE_(m_num)
1241 return *this;
1242}
1243
1244inline sc_fxnum_bitref &
1245sc_fxnum_bitref::operator = (bool a)
1246{
1247 set(a);
1248 SC_FXNUM_OBSERVER_WRITE_(m_num)
1249 return *this;
1250}
1251
1252inline sc_fxnum_bitref &
1253sc_fxnum_bitref::operator &= (const sc_fxnum_bitref &b)
1254{
1255 SC_FXNUM_OBSERVER_READ_(m_num)
1256 SC_FXNUM_OBSERVER_READ_(b.m_num)
1257 set(get() && b.get());
1258 SC_FXNUM_OBSERVER_WRITE_(m_num)
1259 return *this;
1260}
1261
1262inline sc_fxnum_bitref &
1263sc_fxnum_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1264{
1265 SC_FXNUM_OBSERVER_READ_(m_num)
1266 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1267 set(get() && b.get());
1268 SC_FXNUM_OBSERVER_WRITE_(m_num)
1269 return *this;
1270}
1271
1272inline sc_fxnum_bitref &
1273sc_fxnum_bitref::operator &= (const sc_bit &b)
1274{
1275 SC_FXNUM_OBSERVER_READ_(m_num)
1276 set(get() && static_cast<bool>(b));
1277 SC_FXNUM_OBSERVER_WRITE_(m_num)
1278 return *this;
1279}
1280
1281inline sc_fxnum_bitref &
1282sc_fxnum_bitref::operator &= (bool b)
1283{
1284 SC_FXNUM_OBSERVER_READ_(m_num)
1285 set(get() && b);
1286 SC_FXNUM_OBSERVER_WRITE_(m_num)
1287 return *this;
1288}
1289
1290
1291inline sc_fxnum_bitref &
1292sc_fxnum_bitref::operator |= (const sc_fxnum_bitref &b)
1293{
1294 SC_FXNUM_OBSERVER_READ_(m_num)
1295 SC_FXNUM_OBSERVER_READ_(b.m_num)
1296 set(get() || b.get());
1297 SC_FXNUM_OBSERVER_WRITE_(m_num)
1298 return *this;
1299}
1300
1301inline sc_fxnum_bitref &
1302sc_fxnum_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1303{
1304 SC_FXNUM_OBSERVER_READ_(m_num)
1305 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1306 set(get() || b.get());
1307 SC_FXNUM_OBSERVER_WRITE_(m_num)
1308 return *this;
1309}
1310
1311inline sc_fxnum_bitref &
1312sc_fxnum_bitref::operator |= (const sc_bit &b)
1313{
1314 SC_FXNUM_OBSERVER_READ_(m_num)
1315 set(get() || static_cast<bool>(b));
1316 SC_FXNUM_OBSERVER_WRITE_(m_num)
1317 return *this;
1318}
1319
1320inline sc_fxnum_bitref &
1321sc_fxnum_bitref::operator |= (bool b)
1322{
1323 SC_FXNUM_OBSERVER_READ_(m_num)
1324 set(get() || b);
1325 SC_FXNUM_OBSERVER_WRITE_(m_num)
1326 return *this;
1327}
1328
1329
1330inline sc_fxnum_bitref &
1331sc_fxnum_bitref::operator ^= (const sc_fxnum_bitref &b)
1332{
1333 SC_FXNUM_OBSERVER_READ_(m_num)
1334 SC_FXNUM_OBSERVER_READ_(b.m_num)
1335 set(get() != b.get());
1336 SC_FXNUM_OBSERVER_WRITE_(m_num)
1337 return *this;
1338}
1339
1340inline sc_fxnum_bitref &
1341sc_fxnum_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1342{
1343 SC_FXNUM_OBSERVER_READ_(m_num)
1344 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1345 set(get() != b.get());
1346 SC_FXNUM_OBSERVER_WRITE_(m_num)
1347 return *this;
1348}
1349
1350inline sc_fxnum_bitref &
1351sc_fxnum_bitref::operator ^= (const sc_bit &b)
1352{
1353 SC_FXNUM_OBSERVER_READ_(m_num)
1354 set(get() != static_cast<bool>(b));
1355 SC_FXNUM_OBSERVER_WRITE_(m_num)
1356 return *this;
1357}
1358
1359inline sc_fxnum_bitref &
1360sc_fxnum_bitref::operator ^= (bool b)
1361{
1362 SC_FXNUM_OBSERVER_READ_(m_num)
1363 set(get() != b);
1364 SC_FXNUM_OBSERVER_WRITE_(m_num)
1365 return *this;
1366}
1367
1368// implicit conversion
1369inline sc_fxnum_bitref::operator bool() const
1370{
1371 SC_FXNUM_OBSERVER_READ_(m_num)
1372 return get();
1373}
1374
1375inline ::std::ostream &
1376operator << (::std::ostream &os, const sc_fxnum_bitref &a)
1377{
1378 a.print(os);
1379 return os;
1380}
1381
1382inline ::std::istream &
1383operator >> (::std::istream &is, sc_fxnum_bitref &a)
1384{
1385 a.scan(is);
1386 return is;
1387}
1388
1389
1390// ----------------------------------------------------------------------------
1391// CLASS : sc_fxnum_fast_bitref
1392//
1393// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
1394// ----------------------------------------------------------------------------
1395
1396// constructor
1397inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1398 sc_fxnum_fast &num_, int idx_) : m_num(num_), m_idx(idx_)
1399{}
1400
1401// copy constructor
1402inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1403 const sc_fxnum_fast_bitref &a) : m_num(a.m_num), m_idx(a.m_idx)
1404{}
1405
1406// assignment operators
1407inline sc_fxnum_fast_bitref &
1408sc_fxnum_fast_bitref::operator = (const sc_fxnum_bitref &a)
1409{
1410 SC_FXNUM_OBSERVER_READ_(a.m_num)
1411 set(a.get());
1412 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1413 return *this;
1414}
1415
1416inline sc_fxnum_fast_bitref &
1417sc_fxnum_fast_bitref::operator = (const sc_fxnum_fast_bitref &a)
1418{
1419 if (&a != this) {
1420 SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1421 set(a.get());
1422 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1423 }
1424 return *this;
1425}
1426
1427inline sc_fxnum_fast_bitref &
1428sc_fxnum_fast_bitref::operator = (const sc_bit &a)
1429{
1430 set(static_cast<bool>(a));
1431 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1432 return *this;
1433}
1434
1435inline sc_fxnum_fast_bitref &
1436sc_fxnum_fast_bitref::operator = (bool a)
1437{
1438 set(a);
1439 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1440 return *this;
1441}
1442
1443
1444inline sc_fxnum_fast_bitref &
1445sc_fxnum_fast_bitref::operator &= (const sc_fxnum_bitref &b)
1446{
1447 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1448 SC_FXNUM_OBSERVER_READ_(b.m_num)
1449 set(get() && b.get());
1450 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1451 return *this;
1452}
1453
1454inline sc_fxnum_fast_bitref &
1455sc_fxnum_fast_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1456{
1457 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1458 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1459 set(get() && b.get());
1460 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1461 return *this;
1462}
1463
1464inline sc_fxnum_fast_bitref &
1465sc_fxnum_fast_bitref::operator &= (const sc_bit &b)
1466{
1467 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1468 set(get() && static_cast<bool>(b));
1469 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1470 return *this;
1471}
1472
1473inline sc_fxnum_fast_bitref &
1474sc_fxnum_fast_bitref::operator &= (bool b)
1475{
1476 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1477 set(get() && b);
1478 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1479 return *this;
1480}
1481
1482
1483inline sc_fxnum_fast_bitref &
1484sc_fxnum_fast_bitref::operator |= (const sc_fxnum_bitref &b)
1485{
1486 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1487 SC_FXNUM_OBSERVER_READ_(b.m_num)
1488 set(get() || b.get());
1489 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1490 return *this;
1491}
1492
1493inline sc_fxnum_fast_bitref &
1494sc_fxnum_fast_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1495{
1496 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1497 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1498 set(get() || b.get());
1499 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1500 return *this;
1501}
1502
1503inline sc_fxnum_fast_bitref &
1504sc_fxnum_fast_bitref::operator |= (const sc_bit &b)
1505{
1506 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1507 set(get() || static_cast<bool>(b));
1508 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1509 return *this;
1510}
1511
1512inline sc_fxnum_fast_bitref &
1513sc_fxnum_fast_bitref::operator |= (bool b)
1514{
1515 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1516 set(get() || b);
1517 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1518 return *this;
1519}
1520
1521
1522inline sc_fxnum_fast_bitref &
1523sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_bitref &b)
1524{
1525 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1526 SC_FXNUM_OBSERVER_READ_(b.m_num)
1527 set(get() != b.get());
1528 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1529 return *this;
1530}
1531
1532inline sc_fxnum_fast_bitref &
1533sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1534{
1535 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1536 SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1537 set(get() != b.get());
1538 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1539 return *this;
1540}
1541
1542inline sc_fxnum_fast_bitref &
1543sc_fxnum_fast_bitref::operator ^= (const sc_bit &b)
1544{
1545 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1546 set(get() != static_cast<bool>(b));
1547 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1548 return *this;
1549}
1550
1551inline sc_fxnum_fast_bitref &
1552sc_fxnum_fast_bitref::operator ^= (bool b)
1553{
1554 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1555 set(get() != b);
1556 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1557 return *this;
1558}
1559
1560
1561// implicit conversion
1562inline sc_fxnum_fast_bitref::operator bool() const
1563{
1564 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1565 return get();
1566}
1567
1568inline ::std::ostream &
1569operator << (::std::ostream &os, const sc_fxnum_fast_bitref &a)
1570{
1571 a.print(os);
1572 return os;
1573}
1574
1575inline ::std::istream &
1576operator >> (::std::istream &is, sc_fxnum_fast_bitref &a)
1577{
1578 a.scan(is);
1579 return is;
1580}
1581
1582
1583// ----------------------------------------------------------------------------
1584// CLASS : sc_fxnum_subref
1585//
1586// Proxy class for part-selection in class sc_fxnum,
1587// behaves like sc_bv_base.
1588// ----------------------------------------------------------------------------
1589
1590// constructor
1591inline sc_fxnum_subref::sc_fxnum_subref(sc_fxnum &num_, int from_, int to_) :
1592 m_num(num_), m_from(from_), m_to(to_),
1593 m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1594{}
1595
1596// copy constructor
1597inline sc_fxnum_subref::sc_fxnum_subref(const sc_fxnum_subref &a) :
1598 m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1599 m_bv(*new sc_bv_base(a.m_bv))
1600{}
1601
1602// destructor
1603inline sc_fxnum_subref::~sc_fxnum_subref()
1604{
1605 delete &m_bv;
1606}
1607
1608// assignment operators
1609inline sc_fxnum_subref &
1610sc_fxnum_subref::operator = (const sc_fxnum_subref &a)
1611{
1612 if (&a != this) {
1613 m_bv = static_cast<sc_bv_base>(a);
1614 set();
1615 SC_FXNUM_OBSERVER_WRITE_(m_num)
1616 }
1617 return *this;
1618}
1619
1620inline sc_fxnum_subref &
1621sc_fxnum_subref::operator = (const sc_fxnum_fast_subref &a)
1622{
1623 m_bv = static_cast<sc_bv_base>(a);
1624 set();
1625 SC_FXNUM_OBSERVER_WRITE_(m_num)
1626 return *this;
1627}
1628
1629#define DEFN_ASN_OP_T(tp) \
1630inline sc_fxnum_subref & \
1631sc_fxnum_subref::operator = (tp a) \
1632{ \
1633 m_bv = a; \
1634 set(); \
1635 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1636 return *this; \
1637}
1638
1639DEFN_ASN_OP_T(const sc_bv_base &)
1640DEFN_ASN_OP_T(const sc_lv_base &)
1641DEFN_ASN_OP_T(const char *)
1642DEFN_ASN_OP_T(const bool *)
1643DEFN_ASN_OP_T(const sc_signed &)
1644DEFN_ASN_OP_T(const sc_unsigned &)
1645DEFN_ASN_OP_T(const sc_int_base &)
1646DEFN_ASN_OP_T(const sc_uint_base &)
1647DEFN_ASN_OP_T(int64)
1648DEFN_ASN_OP_T(uint64)
1649DEFN_ASN_OP_T(int)
1650DEFN_ASN_OP_T(unsigned int)
1651DEFN_ASN_OP_T(long)
1652DEFN_ASN_OP_T(unsigned long)
1653DEFN_ASN_OP_T(char)
1654
1655#undef DEFN_ASN_OP_T
1656
1657#define DEFN_ASN_OP_T(op, tp) \
1658inline sc_fxnum_subref & \
1659sc_fxnum_subref::operator op ## = (tp a) \
1660{ \
1661 SC_FXNUM_OBSERVER_READ_(m_num) \
1662 get(); \
1663 m_bv = m_bv op a; \
1664 set(); \
1665 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1666 return *this; \
1667}
1668
1669#define DEFN_ASN_OP(op) \
1670inline sc_fxnum_subref & \
1671sc_fxnum_subref::operator op ## = (const sc_fxnum_subref &a) \
1672{ \
1673 SC_FXNUM_OBSERVER_READ_(m_num) \
1674 get(); \
1675 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1676 set(); \
1677 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1678 return *this; \
1679} \
1680 \
1681inline sc_fxnum_subref & \
1682sc_fxnum_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1683{ \
1684 SC_FXNUM_OBSERVER_READ_(m_num) \
1685 get(); \
1686 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1687 set(); \
1688 SC_FXNUM_OBSERVER_WRITE_(m_num) \
1689 return *this; \
1690} \
1691 \
1692DEFN_ASN_OP_T(op, const sc_bv_base &) \
1693DEFN_ASN_OP_T(op, const sc_lv_base &)
1694
1695DEFN_ASN_OP( &)
1696DEFN_ASN_OP(|)
1697DEFN_ASN_OP(^)
1698
1699#undef DEFN_ASN_OP_T
1700#undef DEFN_ASN_OP
1701
1702// relational operators
1703#define DEFN_REL_OP_T(op, tp) \
1704inline bool \
1705operator op (const sc_fxnum_subref &a, tp b) \
1706{ \
1707 return (static_cast<sc_bv_base>(a) op b); \
1708} \
1709 \
1710inline bool \
1711operator op (tp a, const sc_fxnum_subref &b) \
1712{ \
1713 return (static_cast<sc_bv_base>(b) op a); \
1714}
1715
1716#define DEFN_REL_OP(op) \
1717inline bool \
1718operator op (const sc_fxnum_subref &a, const sc_fxnum_subref &b) \
1719{ \
1720 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1721} \
1722 \
1723inline bool \
1724operator op (const sc_fxnum_subref &a, const sc_fxnum_fast_subref &b) \
1725{ \
1726 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1727} \
1728 \
1729DEFN_REL_OP_T(op, const sc_bv_base &) \
1730DEFN_REL_OP_T(op, const sc_lv_base &) \
1731DEFN_REL_OP_T(op, const char *) \
1732DEFN_REL_OP_T(op, const bool *) \
1733DEFN_REL_OP_T(op, const sc_signed &) \
1734DEFN_REL_OP_T(op, const sc_unsigned &) \
1735DEFN_REL_OP_T(op, int) \
1736DEFN_REL_OP_T(op, unsigned int) \
1737DEFN_REL_OP_T(op, long) \
1738DEFN_REL_OP_T(op, unsigned long)
1739
1740DEFN_REL_OP(==)
1741DEFN_REL_OP(!=)
1742
1743#undef DEFN_REL_OP_T
1744#undef DEFN_REL_OP
1745
1746
1747// reduce functions
1748
1749#define DEFN_RED_FNC(fnc) \
1750inline bool \
1751sc_fxnum_subref::fnc() const \
1752{ \
1753 SC_FXNUM_OBSERVER_READ_(m_num) \
1754 get(); \
1755 return static_cast<bool>(m_bv.fnc()); \
1756}
1757
1758DEFN_RED_FNC(and_reduce)
1759DEFN_RED_FNC(nand_reduce)
1760DEFN_RED_FNC(or_reduce)
1761DEFN_RED_FNC(nor_reduce)
1762DEFN_RED_FNC(xor_reduce)
1763DEFN_RED_FNC(xnor_reduce)
1764
1765#undef DEFN_RED_FNC
1766
1767// query parameter
1768inline int
1769sc_fxnum_subref::length() const
1770{
1771 return m_bv.length();
1772}
1773
1774// explicit conversions
1775inline int
1776sc_fxnum_subref::to_int() const
1777{
1778 SC_FXNUM_OBSERVER_READ_(m_num)
1779 get();
1780 return m_bv.to_int();
1781}
1782
1783inline int64
1784sc_fxnum_subref::to_int64() const
1785{
1786 SC_FXNUM_OBSERVER_READ_(m_num)
1787 get();
1788 return m_bv.to_int64();
1789}
1790
1791inline unsigned int
1792sc_fxnum_subref::to_uint() const
1793{
1794 SC_FXNUM_OBSERVER_READ_(m_num)
1795 get();
1796 return m_bv.to_uint();
1797}
1798
1799inline uint64
1800sc_fxnum_subref::to_uint64() const
1801{
1802 SC_FXNUM_OBSERVER_READ_(m_num)
1803 get();
1804 return m_bv.to_uint64();
1805}
1806
1807inline long
1808sc_fxnum_subref::to_long() const
1809{
1810 SC_FXNUM_OBSERVER_READ_(m_num)
1811 get();
1812 return m_bv.to_long();
1813}
1814
1815inline unsigned long
1816sc_fxnum_subref::to_ulong() const
1817{
1818 SC_FXNUM_OBSERVER_READ_(m_num)
1819 get();
1820 return m_bv.to_ulong();
1821}
1822
1823
1824inline const std::string
1825sc_fxnum_subref::to_string() const
1826{
1827 get();
1828 return m_bv.to_string();
1829}
1830
1831inline const std::string
1832sc_fxnum_subref::to_string(sc_numrep numrep) const
1833{
1834 get();
1835 return m_bv.to_string(numrep);
1836}
1837
1838inline const std::string
1839sc_fxnum_subref::to_string(sc_numrep numrep, bool w_prefix) const
1840{
1841 get();
1842 return m_bv.to_string(numrep, w_prefix);
1843}
1844
1845
1846// implicit conversion
1847inline sc_fxnum_subref::operator sc_bv_base () const
1848{
1849 SC_FXNUM_OBSERVER_READ_(m_num)
1850 get();
1851 return m_bv;
1852}
1853
1854
1855inline ::std::ostream &
1856operator << (::std::ostream &os, const sc_fxnum_subref &a)
1857{
1858 a.print(os);
1859 return os;
1860}
1861
1862inline ::std::istream &
1863operator >> (::std::istream &is, sc_fxnum_subref &a)
1864{
1865 a.scan(is);
1866 return is;
1867}
1868
1869
1870// ----------------------------------------------------------------------------
1871// CLASS : sc_fxnum_fast_subref
1872//
1873// Proxy class for part-selection in class sc_fxnum_fast,
1874// behaves like sc_bv_base.
1875// ----------------------------------------------------------------------------
1876
1877// constructor
1878
1879inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1880 sc_fxnum_fast &num_, int from_, int to_) :
1881 m_num(num_), m_from(from_), m_to(to_),
1882 m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1883{}
1884
1885
1886// copy constructor
1887inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1888 const sc_fxnum_fast_subref &a) :
1889 m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1890 m_bv(*new sc_bv_base(a.m_bv))
1891{}
1892
1893
1894// destructor
1895inline sc_fxnum_fast_subref::~sc_fxnum_fast_subref()
1896{
1897 delete &m_bv;
1898}
1899
1900
1901// assignment operators
1902inline sc_fxnum_fast_subref &
1903sc_fxnum_fast_subref::operator = (const sc_fxnum_subref &a)
1904{
1905 m_bv = static_cast<sc_bv_base>(a);
1906 set();
1907 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1908 return *this;
1909}
1910
1911inline sc_fxnum_fast_subref &
1912sc_fxnum_fast_subref::operator = (const sc_fxnum_fast_subref &a)
1913{
1914 if (&a != this) {
1915 m_bv = static_cast<sc_bv_base>(a);
1916 set();
1917 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1918 }
1919 return *this;
1920}
1921
1922#define DEFN_ASN_OP_T(tp) \
1923inline sc_fxnum_fast_subref & \
1924sc_fxnum_fast_subref::operator = (tp a) \
1925{ \
1926 m_bv = a; \
1927 set(); \
1928 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1929 return *this; \
1930}
1931
1932DEFN_ASN_OP_T(const sc_bv_base &)
1933DEFN_ASN_OP_T(const sc_lv_base &)
1934DEFN_ASN_OP_T(const char *)
1935DEFN_ASN_OP_T(const bool *)
1936DEFN_ASN_OP_T(const sc_signed &)
1937DEFN_ASN_OP_T(const sc_unsigned &)
1938DEFN_ASN_OP_T(const sc_int_base &)
1939DEFN_ASN_OP_T(const sc_uint_base &)
1940DEFN_ASN_OP_T(int64)
1941DEFN_ASN_OP_T(uint64)
1942DEFN_ASN_OP_T(int)
1943DEFN_ASN_OP_T(unsigned int)
1944DEFN_ASN_OP_T(long)
1945DEFN_ASN_OP_T(unsigned long)
1946DEFN_ASN_OP_T(char)
1947
1948#undef DEFN_ASN_OP_T
1949
1950
1951#define DEFN_ASN_OP_T(op, tp) \
1952inline sc_fxnum_fast_subref & \
1953sc_fxnum_fast_subref::operator op ## = (tp a) \
1954{ \
1955 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1956 get(); \
1957 m_bv = m_bv op a; \
1958 set(); \
1959 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1960 return *this; \
1961}
1962
1963#define DEFN_ASN_OP(op) \
1964inline sc_fxnum_fast_subref & \
1965sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_subref &a) \
1966{ \
1967 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1968 get(); \
1969 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1970 set(); \
1971 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1972 return *this; \
1973} \
1974 \
1975inline sc_fxnum_fast_subref & \
1976sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1977{ \
1978 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1979 get(); \
1980 m_bv = m_bv op static_cast<sc_bv_base>(a); \
1981 set(); \
1982 SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1983 return *this; \
1984} \
1985 \
1986DEFN_ASN_OP_T(op, const sc_bv_base &) \
1987DEFN_ASN_OP_T(op, const sc_lv_base &)
1988
1989DEFN_ASN_OP(&)
1990DEFN_ASN_OP(|)
1991DEFN_ASN_OP(^)
1992
1993#undef DEFN_ASN_OP_T
1994#undef DEFN_ASN_OP
1995
1996
1997// relational operators
1998
1999#define DEFN_REL_OP_T(op, tp) \
2000inline bool \
2001operator op (const sc_fxnum_fast_subref &a, tp b) \
2002{ \
2003 return (static_cast<sc_bv_base>(a) op b); \
2004} \
2005 \
2006inline bool \
2007operator op (tp a, const sc_fxnum_fast_subref &b) \
2008{ \
2009 return (static_cast<sc_bv_base>(b) op a); \
2010}
2011
2012#define DEFN_REL_OP(op) \
2013inline bool \
2014operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_fast_subref &b) \
2015{ \
2016 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2017} \
2018 \
2019inline bool \
2020operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_subref &b) \
2021{ \
2022 return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2023} \
2024 \
2025DEFN_REL_OP_T(op, const sc_bv_base &) \
2026DEFN_REL_OP_T(op, const sc_lv_base &) \
2027DEFN_REL_OP_T(op, const char *) \
2028DEFN_REL_OP_T(op, const bool *) \
2029DEFN_REL_OP_T(op, const sc_signed &) \
2030DEFN_REL_OP_T(op, const sc_unsigned &) \
2031DEFN_REL_OP_T(op, int) \
2032DEFN_REL_OP_T(op, unsigned int) \
2033DEFN_REL_OP_T(op, long) \
2034DEFN_REL_OP_T(op, unsigned long)
2035
2036DEFN_REL_OP(==)
2037DEFN_REL_OP(!=)
2038
2039#undef DEFN_REL_OP_T
2040#undef DEFN_REL_OP
2041
2042// reduce functions
2043#define DEFN_RED_FNC(fnc) \
2044inline bool \
2045sc_fxnum_fast_subref::fnc() const \
2046{ \
2047 SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
2048 get(); \
2049 return static_cast<bool>(m_bv.fnc()); \
2050}
2051
2052DEFN_RED_FNC(and_reduce)
2053DEFN_RED_FNC(nand_reduce)
2054DEFN_RED_FNC(or_reduce)
2055DEFN_RED_FNC(nor_reduce)
2056DEFN_RED_FNC(xor_reduce)
2057DEFN_RED_FNC(xnor_reduce)
2058
2059#undef DEFN_RED_FNC
2060
2061// query parameter
2062inline int
2063sc_fxnum_fast_subref::length() const
2064{
2065 return m_bv.length();
2066}
2067
2068// explicit conversions
2069inline int
2070sc_fxnum_fast_subref::to_int() const
2071{
2072 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2073 get();
2074 return m_bv.to_int();
2075}
2076
2077inline int64
2078sc_fxnum_fast_subref::to_int64() const
2079{
2080 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2081 get();
2082 return m_bv.to_int64();
2083}
2084
2085inline unsigned int
2086sc_fxnum_fast_subref::to_uint() const
2087{
2088 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2089 get();
2090 return m_bv.to_uint();
2091}
2092
2093inline uint64
2094sc_fxnum_fast_subref::to_uint64() const
2095{
2096 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2097 get();
2098 return m_bv.to_uint64();
2099}
2100
2101inline long
2102sc_fxnum_fast_subref::to_long() const
2103{
2104 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2105 get();
2106 return m_bv.to_long();
2107}
2108
2109inline unsigned long
2110sc_fxnum_fast_subref::to_ulong() const
2111{
2112 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2113 get();
2114 return m_bv.to_ulong();
2115}
2116
2117inline const std::string
2118sc_fxnum_fast_subref::to_string() const
2119{
2120 get();
2121 return m_bv.to_string();
2122}
2123
2124inline const std::string
2125sc_fxnum_fast_subref::to_string(sc_numrep numrep) const
2126{
2127 get();
2128 return m_bv.to_string(numrep);
2129}
2130
2131inline const std::string
2132sc_fxnum_fast_subref::to_string(sc_numrep numrep, bool w_prefix) const
2133{
2134 get();
2135 return m_bv.to_string(numrep, w_prefix);
2136}
2137
2138
2139// implicit conversion
2140inline sc_fxnum_fast_subref::operator sc_bv_base () const
2141{
2142 SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2143 get();
2144 return m_bv;
2145}
2146
2147inline ::std::ostream &
2148operator << (::std::ostream &os, const sc_fxnum_fast_subref &a)
2149{
2150 a.print(os);
2151 return os;
2152}
2153
2154inline ::std::istream &
2155operator >> (::std::istream &is, sc_fxnum_fast_subref &a)
2156{
2157 a.scan(is);
2158 return is;
2159}
2160
2161
2162// ----------------------------------------------------------------------------
2163// CLASS : sc_fxnum
2164//
2165// Base class for the fixed-point types; arbitrary precision.
2166// ----------------------------------------------------------------------------
2167
2168inline sc_fxnum_observer *
2169sc_fxnum::observer() const
2170{
2171 return m_observer;
2172}
2173
2174inline void
2175sc_fxnum::cast()
2176{
2177 SC_ERROR_IF_(!m_rep->is_normal(), "invalid fixed-point value");
2178
2179 if (m_params.cast_switch() == SC_ON)
2180 m_rep->cast(m_params, m_q_flag, m_o_flag);
2181}
2182
2183// constructors
2184inline sc_fxnum::sc_fxnum(const sc_fxtype_params &type_params_,
2185 sc_enc enc_, const sc_fxcast_switch &cast_sw,
2186 sc_fxnum_observer *observer_) :
2187 m_rep(new scfx_rep), m_params(type_params_, enc_, cast_sw),
2188 m_q_flag(false), m_o_flag(false), m_observer(observer_)
2189{
2190 SC_FXNUM_OBSERVER_DEFAULT_
2191 SC_FXNUM_OBSERVER_CONSTRUCT_(*this)
2192}
2193
2194#define DEFN_CTOR_T(tp, arg) \
2195inline sc_fxnum::sc_fxnum(tp a, const sc_fxtype_params &type_params_, \
2196 sc_enc enc_, const sc_fxcast_switch &cast_sw, \
2197 sc_fxnum_observer *observer_) : \
2198 m_rep(new scfx_rep(arg)), m_params(type_params_, enc_, cast_sw), \
2199 m_q_flag(false), m_o_flag(false), m_observer(observer_) \
2200{ \
2201 SC_FXNUM_OBSERVER_DEFAULT_ \
2202 cast(); \
2203 SC_FXNUM_OBSERVER_CONSTRUCT_(*this) \
2204 SC_FXNUM_OBSERVER_WRITE_(*this) \
2205}
2206
2207#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, a)
2208#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, *a.m_rep)
2209#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
2210#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp, a.value())
2211
2212DEFN_CTOR_T_A(int)
2213DEFN_CTOR_T_A(unsigned int)
2214DEFN_CTOR_T_A(long)
2215DEFN_CTOR_T_A(unsigned long)
2216DEFN_CTOR_T_A(float)
2217DEFN_CTOR_T_A(double)
2218DEFN_CTOR_T_A(const char *)
2219DEFN_CTOR_T_B(const sc_fxval &)
2220DEFN_CTOR_T_C(const sc_fxval_fast &)
2221DEFN_CTOR_T_B(const sc_fxnum &)
2222DEFN_CTOR_T_C(const sc_fxnum_fast &)
2223#ifndef SC_FX_EXCLUDE_OTHER
2224DEFN_CTOR_T_A(int64)
2225DEFN_CTOR_T_A(uint64)
2226DEFN_CTOR_T_D(const sc_int_base &)
2227DEFN_CTOR_T_D(const sc_uint_base &)
2228DEFN_CTOR_T_A(const sc_signed &)
2229DEFN_CTOR_T_A(const sc_unsigned &)
2230#endif
2231
2232#undef DEFN_CTOR_T
2233#undef DEFN_CTOR_T_A
2234#undef DEFN_CTOR_T_B
2235#undef DEFN_CTOR_T_C
2236#undef DEFN_CTOR_T_D
2237
2238inline sc_fxnum::~sc_fxnum()
2239{
2240 SC_FXNUM_OBSERVER_DESTRUCT_(*this)
2241 delete m_rep;
2242}
2243
2244// internal use only;
2245inline const scfx_rep *
2246sc_fxnum::get_rep() const
2247{
2248 SC_FXNUM_OBSERVER_READ_(*this)
2249 return m_rep;
2250}
2251
2252// unary operators
2253inline const sc_fxval
2254sc_fxnum::operator - () const
2255{
2256 SC_FXNUM_OBSERVER_READ_(*this)
2257 return sc_fxval(sc_dt::neg_scfx_rep(*m_rep));
2258}
2259
2260inline const sc_fxval
2261sc_fxnum::operator + () const
2262{
2263 SC_FXNUM_OBSERVER_READ_(*this)
2264 return sc_fxval(new scfx_rep(*m_rep));
2265}
2266
2267// unary functions
2268inline void
2269neg(sc_fxval &c, const sc_fxnum &a)
2270{
2271 SC_FXNUM_OBSERVER_READ_(a)
2272 c.set_rep(sc_dt::neg_scfx_rep(*a.m_rep));
2273}
2274
2275inline void
2276neg(sc_fxnum &c, const sc_fxnum &a)
2277{
2278 SC_FXNUM_OBSERVER_READ_(a)
2279 delete c.m_rep;
2280 c.m_rep = sc_dt::neg_scfx_rep(*a.m_rep);
2281 c.cast();
2282 SC_FXNUM_OBSERVER_WRITE_(c)
2283}
2284
2285// binary operators
2286#define DEFN_BIN_OP_T(op, fnc, tp) \
2287inline const sc_fxval \
2288operator op (const sc_fxnum &a, tp b) \
2289{ \
2290 SC_FXNUM_OBSERVER_READ_(a) \
2291 sc_fxval tmp(b); \
2292 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2293} \
2294 \
2295inline const sc_fxval \
2296operator op (tp a, const sc_fxnum &b) \
2297{ \
2298 SC_FXNUM_OBSERVER_READ_(b) \
2299 sc_fxval tmp(a); \
2300 return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2301}
2302
2303#ifndef SC_FX_EXCLUDE_OTHER
2304#define DEFN_BIN_OP_OTHER(op, fnc) \
2305DEFN_BIN_OP_T(op, fnc, int64) \
2306DEFN_BIN_OP_T(op, fnc, uint64) \
2307DEFN_BIN_OP_T(op, fnc, const sc_int_base &) \
2308DEFN_BIN_OP_T(op, fnc, const sc_uint_base &) \
2309DEFN_BIN_OP_T(op, fnc, const sc_signed &) \
2310DEFN_BIN_OP_T(op, fnc, const sc_unsigned &)
2311#else
2312#define DEFN_BIN_OP_OTHER(op, fnc)
2313#endif
2314
2315#define DEFN_BIN_OP(op, fnc) \
2316inline const sc_fxval \
2317operator op (const sc_fxnum &a, const sc_fxnum &b) \
2318{ \
2319 SC_FXNUM_OBSERVER_READ_(a) \
2320 SC_FXNUM_OBSERVER_READ_(b) \
2321 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2322} \
2323 \
2324inline const sc_fxval \
2325operator op (const sc_fxnum &a, const sc_fxval &b) \
2326{ \
2327 SC_FXNUM_OBSERVER_READ_(a) \
2328 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2329} \
2330 \
2331inline const sc_fxval \
2332operator op (const sc_fxval &a, const sc_fxnum &b) \
2333{ \
2334 SC_FXNUM_OBSERVER_READ_(b) \
2335 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2336} \
2337 \
2338DEFN_BIN_OP_T(op, fnc, int) \
2339DEFN_BIN_OP_T(op, fnc, unsigned int) \
2340DEFN_BIN_OP_T(op, fnc, long) \
2341DEFN_BIN_OP_T(op, fnc, unsigned long) \
2342DEFN_BIN_OP_T(op, fnc, float) \
2343DEFN_BIN_OP_T(op, fnc, double) \
2344DEFN_BIN_OP_T(op, fnc, const char *) \
2345DEFN_BIN_OP_T(op, fnc, const sc_fxval_fast &) \
2346DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &) \
2347DEFN_BIN_OP_OTHER(op, fnc)
2348
2349DEFN_BIN_OP(*, mult)
2350DEFN_BIN_OP(+, add)
2351DEFN_BIN_OP(-, sub)
2352// don't use macros
2353//DEFN_BIN_OP(/, div)
2354inline const sc_fxval
2355operator / (const sc_fxnum &a, const sc_fxnum &b)
2356{
2357 SC_FXNUM_OBSERVER_READ_(a)
2358 SC_FXNUM_OBSERVER_READ_(b)
2359 return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.m_rep));
2360}
2361
2362inline const sc_fxval
2363operator / (const sc_fxnum &a, const sc_fxval &b)
2364{
2365 SC_FXNUM_OBSERVER_READ_(a)
2366 return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.get_rep()));
2367}
2368
2369inline const sc_fxval
2370operator / (const sc_fxval &a, const sc_fxnum &b)
2371{
2372 SC_FXNUM_OBSERVER_READ_(b)
2373 return sc_fxval(sc_dt::div_scfx_rep(*a.get_rep(), *b.m_rep));
2374}
2375
2376DEFN_BIN_OP_T(/, div, int)
2377DEFN_BIN_OP_T(/, div, unsigned int)
2378DEFN_BIN_OP_T(/, div, long)
2379DEFN_BIN_OP_T(/, div, unsigned long)
2380DEFN_BIN_OP_T(/, div, float)
2381DEFN_BIN_OP_T(/, div, double)
2382DEFN_BIN_OP_T(/, div, const char *)
2383DEFN_BIN_OP_T(/, div, const sc_fxval_fast &)
2384DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
2385//DEFN_BIN_OP_OTHER(/, div)
2386
2387DEFN_BIN_OP_T(/, div, int64)
2388DEFN_BIN_OP_T(/, div, uint64)
2389DEFN_BIN_OP_T(/, div, const sc_int_base &)
2390DEFN_BIN_OP_T(/, div, const sc_uint_base &)
2391DEFN_BIN_OP_T(/, div, const sc_signed &)
2392DEFN_BIN_OP_T(/, div, const sc_unsigned &)
2393
2394#undef DEFN_BIN_OP_T
2395#undef DEFN_BIN_OP_OTHER
2396#undef DEFN_BIN_OP
2397
2398inline const sc_fxval
2399operator << (const sc_fxnum &a, int b)
2400{
2401 SC_FXNUM_OBSERVER_READ_(a)
2402 return sc_fxval(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2403}
2404
2405inline const sc_fxval
2406operator >> (const sc_fxnum &a, int b)
2407{
2408 SC_FXNUM_OBSERVER_READ_(a)
2409 return sc_fxval(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2410}
2411
2412// binary functions
2413#define DEFN_BIN_FNC_T(fnc, tp) \
2414inline void \
2415fnc (sc_fxval &c, const sc_fxnum &a, tp b) \
2416{ \
2417 SC_FXNUM_OBSERVER_READ_(a) \
2418 sc_fxval tmp(b); \
2419 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2420} \
2421 \
2422inline void \
2423fnc (sc_fxval &c, tp a, const sc_fxnum &b) \
2424{ \
2425 SC_FXNUM_OBSERVER_READ_(b) \
2426 sc_fxval tmp(a); \
2427 c.set_rep(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2428} \
2429 \
2430inline void \
2431fnc (sc_fxnum &c, const sc_fxnum &a, tp b) \
2432{ \
2433 SC_FXNUM_OBSERVER_READ_(a) \
2434 sc_fxval tmp(b); \
2435 delete c.m_rep; \
2436 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep()); \
2437 c.cast(); \
2438 SC_FXNUM_OBSERVER_WRITE_(c) \
2439} \
2440 \
2441inline void \
2442fnc (sc_fxnum &c, tp a, const sc_fxnum &b) \
2443{ \
2444 SC_FXNUM_OBSERVER_READ_(b) \
2445 sc_fxval tmp(a); \
2446 delete c.m_rep; \
2447 c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep); \
2448 c.cast(); \
2449 SC_FXNUM_OBSERVER_WRITE_(c) \
2450}
2451
2452#define DEFN_BIN_FNC_OTHER(fnc) \
2453DEFN_BIN_FNC_T(fnc, int64) \
2454DEFN_BIN_FNC_T(fnc, uint64) \
2455DEFN_BIN_FNC_T(fnc, const sc_int_base &) \
2456DEFN_BIN_FNC_T(fnc, const sc_uint_base &) \
2457DEFN_BIN_FNC_T(fnc, const sc_signed &) \
2458DEFN_BIN_FNC_T(fnc, const sc_unsigned &)
2459
2460#define DEFN_BIN_FNC(fnc) \
2461inline void \
2462fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxnum &b) \
2463{ \
2464 SC_FXNUM_OBSERVER_READ_(a) \
2465 SC_FXNUM_OBSERVER_READ_(b) \
2466 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2467} \
2468 \
2469inline void \
2470fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxnum &b) \
2471{ \
2472 SC_FXNUM_OBSERVER_READ_(a) \
2473 SC_FXNUM_OBSERVER_READ_(b) \
2474 delete c.m_rep; \
2475 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep); \
2476 c.cast(); \
2477 SC_FXNUM_OBSERVER_WRITE_(c) \
2478} \
2479 \
2480inline void \
2481fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxval &b) \
2482{ \
2483 SC_FXNUM_OBSERVER_READ_(a) \
2484 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2485} \
2486 \
2487inline void \
2488fnc (sc_fxval &c, const sc_fxval &a, const sc_fxnum &b) \
2489{ \
2490 SC_FXNUM_OBSERVER_READ_(b) \
2491 c.set_rep(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2492} \
2493 \
2494inline void \
2495fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxval &b) \
2496{ \
2497 SC_FXNUM_OBSERVER_READ_(a) \
2498 delete c.m_rep; \
2499 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep()); \
2500 c.cast(); \
2501 SC_FXNUM_OBSERVER_WRITE_(c) \
2502} \
2503 \
2504inline void \
2505fnc (sc_fxnum &c, const sc_fxval &a, const sc_fxnum &b) \
2506{ \
2507 SC_FXNUM_OBSERVER_READ_(b) \
2508 delete c.m_rep; \
2509 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep); \
2510 c.cast(); \
2511 SC_FXNUM_OBSERVER_WRITE_(c) \
2512} \
2513 \
2514DEFN_BIN_FNC_T(fnc, int) \
2515DEFN_BIN_FNC_T(fnc, unsigned int) \
2516DEFN_BIN_FNC_T(fnc, long) \
2517DEFN_BIN_FNC_T(fnc, unsigned long) \
2518DEFN_BIN_FNC_T(fnc, float) \
2519DEFN_BIN_FNC_T(fnc, double) \
2520DEFN_BIN_FNC_T(fnc, const char *) \
2521DEFN_BIN_FNC_T(fnc, const sc_fxval_fast &) \
2522DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
2523DEFN_BIN_FNC_OTHER(fnc)
2524
2525DEFN_BIN_FNC(mult)
2526DEFN_BIN_FNC(div)
2527DEFN_BIN_FNC(add)
2528DEFN_BIN_FNC(sub)
2529
2530#undef DEFN_BIN_FNC_T
2531#undef DEFN_BIN_FNC_OTHER
2532#undef DEFN_BIN_FNC
2533
2534inline void
2535lshift(sc_fxval &c, const sc_fxnum &a, int b)
2536{
2537 SC_FXNUM_OBSERVER_READ_(a)
2538 c.set_rep(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2539}
2540
2541inline void
2542rshift(sc_fxval &c, const sc_fxnum &a, int b)
2543{
2544 SC_FXNUM_OBSERVER_READ_(a)
2545 c.set_rep(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2546}
2547
2548inline void
2549lshift(sc_fxnum &c, const sc_fxnum &a, int b)
2550{
2551 SC_FXNUM_OBSERVER_READ_(a)
2552 delete c.m_rep;
2553 c.m_rep = sc_dt::lsh_scfx_rep(*a.m_rep, b);
2554 c.cast();
2555 SC_FXNUM_OBSERVER_WRITE_(c)
2556}
2557
2558inline void
2559rshift(sc_fxnum &c, const sc_fxnum &a, int b)
2560{
2561 SC_FXNUM_OBSERVER_READ_(a)
2562 delete c.m_rep;
2563 c.m_rep = sc_dt::rsh_scfx_rep(*a.m_rep, b);
2564 c.cast();
2565 SC_FXNUM_OBSERVER_WRITE_(c)
2566}
2567
2568// relational (including equality) operators
2569#define DEFN_REL_OP_T(op, ret, tp) \
2570inline bool \
2571operator op (const sc_fxnum &a, tp b) \
2572{ \
2573 SC_FXNUM_OBSERVER_READ_(a) \
2574 sc_fxval tmp(b); \
2575 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.get_rep()); \
2576 return (ret); \
2577} \
2578 \
2579inline bool \
2580operator op (tp a, const sc_fxnum &b) \
2581{ \
2582 SC_FXNUM_OBSERVER_READ_(b) \
2583 sc_fxval tmp(a); \
2584 int result = sc_dt::cmp_scfx_rep(*tmp.get_rep(), *b.m_rep); \
2585 return (ret); \
2586}
2587
2588#define DEFN_REL_OP_OTHER(op, ret) \
2589DEFN_REL_OP_T(op, ret, int64) \
2590DEFN_REL_OP_T(op, ret, uint64) \
2591DEFN_REL_OP_T(op, ret, const sc_int_base &) \
2592DEFN_REL_OP_T(op, ret, const sc_uint_base &) \
2593DEFN_REL_OP_T(op, ret, const sc_signed &) \
2594DEFN_REL_OP_T(op, ret, const sc_unsigned &)
2595
2596#define DEFN_REL_OP(op, ret) \
2597inline bool \
2598operator op (const sc_fxnum &a, const sc_fxnum &b) \
2599{ \
2600 SC_FXNUM_OBSERVER_READ_(a) \
2601 SC_FXNUM_OBSERVER_READ_(b) \
2602 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.m_rep); \
2603 return (ret); \
2604} \
2605 \
2606inline bool \
2607operator op (const sc_fxnum &a, const sc_fxval &b) \
2608{ \
2609 SC_FXNUM_OBSERVER_READ_(a) \
2610 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.get_rep()); \
2611 return (ret); \
2612} \
2613 \
2614inline bool \
2615operator op (const sc_fxval &a, const sc_fxnum &b) \
2616{ \
2617 SC_FXNUM_OBSERVER_READ_(b) \
2618 int result = sc_dt::cmp_scfx_rep(*a.get_rep(), *b.m_rep); \
2619 return (ret); \
2620} \
2621 \
2622DEFN_REL_OP_T(op, ret, int) \
2623DEFN_REL_OP_T(op, ret, unsigned int) \
2624DEFN_REL_OP_T(op, ret, long) \
2625DEFN_REL_OP_T(op, ret, unsigned long) \
2626DEFN_REL_OP_T(op, ret, float) \
2627DEFN_REL_OP_T(op, ret, double) \
2628DEFN_REL_OP_T(op, ret, const char *) \
2629DEFN_REL_OP_T(op, ret, const sc_fxval_fast &) \
2630DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &) \
2631DEFN_REL_OP_OTHER(op, ret)
2632
2633DEFN_REL_OP(<, result < 0)
2634DEFN_REL_OP(<=, result <= 0)
2635DEFN_REL_OP(>, result > 0 && result != 2)
2636DEFN_REL_OP(>=, result >= 0 && result != 2)
2637DEFN_REL_OP(==, result == 0)
2638DEFN_REL_OP(!=, result != 0)
2639
2640#undef DEFN_REL_OP_T
2641#undef DEFN_REL_OP_OTHER
2642#undef DEFN_REL_OP
2643
2644// assignment operators
2645inline sc_fxnum &
2646sc_fxnum::operator = (const sc_fxnum &a)
2647{
2648 if (&a != this) {
2649 SC_FXNUM_OBSERVER_READ_(a)
2650 *m_rep = *a.m_rep;
2651 cast();
2652 SC_FXNUM_OBSERVER_WRITE_(*this)
2653 }
2654 return *this;
2655}
2656
2657inline sc_fxnum &
2658sc_fxnum::operator = (const sc_fxval &a)
2659{
2660 *m_rep = *a.get_rep();
2661 cast();
2662 SC_FXNUM_OBSERVER_WRITE_(*this)
2663 return *this;
2664}
2665
2666#define DEFN_ASN_OP_T(tp) \
2667inline sc_fxnum & \
2668sc_fxnum::operator = (tp a) \
2669{ \
2670 sc_fxval tmp(a); \
2671 *m_rep = *tmp.get_rep(); \
2672 cast(); \
2673 SC_FXNUM_OBSERVER_WRITE_(*this) \
2674 return *this; \
2675}
2676
2677DEFN_ASN_OP_T(int)
2678DEFN_ASN_OP_T(unsigned int)
2679DEFN_ASN_OP_T(long)
2680DEFN_ASN_OP_T(unsigned long)
2681DEFN_ASN_OP_T(float)
2682DEFN_ASN_OP_T(double)
2683DEFN_ASN_OP_T(const char *)
2684DEFN_ASN_OP_T(const sc_fxval_fast &)
2685DEFN_ASN_OP_T(const sc_fxnum_fast &)
2686
2687DEFN_ASN_OP_T(int64)
2688DEFN_ASN_OP_T(uint64)
2689DEFN_ASN_OP_T(const sc_int_base &)
2690DEFN_ASN_OP_T(const sc_uint_base &)
2691DEFN_ASN_OP_T(const sc_signed &)
2692DEFN_ASN_OP_T(const sc_unsigned &)
2693
2694#undef DEFN_ASN_OP_T
2695
2696
2697#define DEFN_ASN_OP_T(op, fnc, tp) \
2698inline sc_fxnum & \
2699sc_fxnum::operator op (tp b) \
2700{ \
2701 SC_FXNUM_OBSERVER_READ_(*this) \
2702 sc_fxval tmp(b); \
2703 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.get_rep()); \
2704 delete m_rep; \
2705 m_rep = new_rep; \
2706 cast(); \
2707 SC_FXNUM_OBSERVER_WRITE_(*this) \
2708 return *this; \
2709}
2710
2711#define DEFN_ASN_OP_OTHER(op, fnc) \
2712DEFN_ASN_OP_T(op, fnc, int64) \
2713DEFN_ASN_OP_T(op, fnc, uint64) \
2714DEFN_ASN_OP_T(op, fnc, const sc_int_base &) \
2715DEFN_ASN_OP_T(op, fnc, const sc_uint_base &) \
2716DEFN_ASN_OP_T(op, fnc, const sc_signed &) \
2717DEFN_ASN_OP_T(op, fnc, const sc_unsigned &)
2718
2719#define DEFN_ASN_OP(op, fnc) \
2720inline sc_fxnum & \
2721sc_fxnum::operator op (const sc_fxnum &b) \
2722{ \
2723 SC_FXNUM_OBSERVER_READ_(*this) \
2724 SC_FXNUM_OBSERVER_READ_(b) \
2725 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.m_rep); \
2726 delete m_rep; \
2727 m_rep = new_rep; \
2728 cast(); \
2729 SC_FXNUM_OBSERVER_WRITE_(*this) \
2730 return *this; \
2731} \
2732 \
2733inline sc_fxnum & \
2734sc_fxnum::operator op (const sc_fxval &b) \
2735{ \
2736 SC_FXNUM_OBSERVER_READ_(*this) \
2737 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
2738 delete m_rep; \
2739 m_rep = new_rep; \
2740 cast(); \
2741 SC_FXNUM_OBSERVER_WRITE_(*this) \
2742 return *this; \
2743} \
2744 \
2745DEFN_ASN_OP_T(op, fnc, int) \
2746DEFN_ASN_OP_T(op, fnc, unsigned int) \
2747DEFN_ASN_OP_T(op, fnc, long) \
2748DEFN_ASN_OP_T(op, fnc, unsigned long) \
2749DEFN_ASN_OP_T(op, fnc, float) \
2750DEFN_ASN_OP_T(op, fnc, double) \
2751DEFN_ASN_OP_T(op, fnc, const char *) \
2752DEFN_ASN_OP_T(op, fnc, const sc_fxval_fast &) \
2753DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &) \
2754DEFN_ASN_OP_OTHER(op, fnc)
2755
2756DEFN_ASN_OP(*=, mult)
2757DEFN_ASN_OP(/=, div)
2758DEFN_ASN_OP(+=, add)
2759DEFN_ASN_OP(-=, sub)
2760
2761#undef DEFN_ASN_OP_T
2762#undef DEFN_ASN_OP_OTHER
2763#undef DEFN_ASN_OP
2764
2765
2766inline sc_fxnum &
2767sc_fxnum::operator <<= (int b)
2768{
2769 SC_FXNUM_OBSERVER_READ_(*this)
2770 m_rep->lshift(b);
2771 cast();
2772 SC_FXNUM_OBSERVER_WRITE_(*this)
2773 return *this;
2774}
2775
2776inline sc_fxnum &
2777sc_fxnum::operator >>= (int b)
2778{
2779 SC_FXNUM_OBSERVER_READ_(*this)
2780 m_rep->rshift(b);
2781 cast();
2782 SC_FXNUM_OBSERVER_WRITE_(*this)
2783 return *this;
2784}
2785
2786// auto-increment and auto-decrement
2787inline const sc_fxval
2788sc_fxnum::operator ++ (int)
2789{
2790 sc_fxval c(*this);
2791 (*this) += 1;
2792 return c;
2793}
2794
2795inline const sc_fxval
2796sc_fxnum::operator -- (int)
2797{
2798 sc_fxval c(*this);
2799 (*this) -= 1;
2800 return c;
2801}
2802
2803inline sc_fxnum &
2804sc_fxnum::operator ++ ()
2805{
2806 (*this) += 1;
2807 return *this;
2808}
2809
2810inline sc_fxnum &
2811sc_fxnum::operator -- ()
2812{
2813 (*this) -= 1;
2814 return *this;
2815}
2816
2817// bit selection
2818inline const sc_fxnum_bitref
2819sc_fxnum::operator [] (int i) const
2820{
2821 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2822 return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2823 i - m_params.fwl());
2824}
2825
2826inline sc_fxnum_bitref
2827sc_fxnum::operator [] (int i)
2828{
2829 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2830 return sc_fxnum_bitref(*this, i - m_params.fwl());
2831}
2832
2833inline const sc_fxnum_bitref
2834sc_fxnum::bit(int i) const
2835{
2836 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2837 return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2838 i - m_params.fwl());
2839}
2840
2841inline sc_fxnum_bitref
2842sc_fxnum::bit(int i)
2843{
2844 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2845 return sc_fxnum_bitref(*this, i - m_params.fwl());
2846}
2847
2848// part selection
2849
2850inline const sc_fxnum_subref
2851sc_fxnum::operator () (int i, int j) const
2852{
2853 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2854 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2855
2856 return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2857 i - m_params.fwl(), j - m_params.fwl());
2858}
2859
2860inline sc_fxnum_subref
2861sc_fxnum::operator () (int i, int j)
2862{
2863 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2864 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2865
2866 return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2867}
2868
2869inline const sc_fxnum_subref
2870sc_fxnum::range(int i, int j) const
2871{
2872 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2873 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2874
2875 return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2876 i - m_params.fwl(), j - m_params.fwl());
2877}
2878
2879inline sc_fxnum_subref
2880sc_fxnum::range(int i, int j)
2881{
2882 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2883 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2884
2885 return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2886}
2887
2888
2889inline const sc_fxnum_subref
2890sc_fxnum::operator () () const
2891{
2892 return this->operator () (m_params.wl() - 1, 0);
2893}
2894
2895inline sc_fxnum_subref
2896sc_fxnum::operator () ()
2897{
2898 return this->operator () (m_params.wl() - 1, 0);
2899}
2900
2901inline const sc_fxnum_subref
2902sc_fxnum::range() const
2903{
2904 return this->range(m_params.wl() - 1, 0);
2905}
2906
2907inline sc_fxnum_subref
2908sc_fxnum::range()
2909{
2910 return this->range(m_params.wl() - 1, 0);
2911}
2912
2913// implicit conversion
2914inline sc_fxnum::operator double() const
2915{
2916 SC_FXNUM_OBSERVER_READ_(*this)
2917 return m_rep->to_double();
2918}
2919
2920// explicit conversion to primitive types
2921inline short
2922sc_fxnum::to_short() const
2923{
2924 SC_FXNUM_OBSERVER_READ_(*this)
2925 return static_cast<short>(m_rep->to_uint64());
2926}
2927
2928inline unsigned short
2929sc_fxnum::to_ushort() const
2930{
2931 SC_FXNUM_OBSERVER_READ_(*this)
2932 return static_cast<unsigned short>(m_rep->to_uint64());
2933}
2934
2935inline int
2936sc_fxnum::to_int() const
2937{
2938 SC_FXNUM_OBSERVER_READ_(*this)
2939 return static_cast<int>(m_rep->to_uint64());
2940}
2941
2942inline int64
2943sc_fxnum::to_int64() const
2944{
2945 SC_FXNUM_OBSERVER_READ_(*this)
2946 return static_cast<int64>(m_rep->to_uint64());
2947}
2948
2949inline unsigned int
2950sc_fxnum::to_uint() const
2951{
2952 SC_FXNUM_OBSERVER_READ_(*this)
2953 return static_cast<unsigned int>(m_rep->to_uint64());
2954}
2955
2956inline uint64
2957sc_fxnum::to_uint64() const
2958{
2959 SC_FXNUM_OBSERVER_READ_(*this)
2960 return m_rep->to_uint64();
2961}
2962
2963inline long
2964sc_fxnum::to_long() const
2965{
2966 SC_FXNUM_OBSERVER_READ_(*this)
2967 return static_cast<long>(m_rep->to_uint64());
2968}
2969
2970inline unsigned long
2971sc_fxnum::to_ulong() const
2972{
2973 SC_FXNUM_OBSERVER_READ_(*this)
2974 return static_cast<unsigned long>(m_rep->to_uint64());
2975}
2976
2977inline float
2978sc_fxnum::to_float() const
2979{
2980 SC_FXNUM_OBSERVER_READ_(*this)
2981 return static_cast<float>(m_rep->to_double());
2982}
2983
2984inline double
2985sc_fxnum::to_double() const
2986{
2987 SC_FXNUM_OBSERVER_READ_(*this)
2988 return m_rep->to_double();
2989}
2990
2991// query value
2992inline bool
2993sc_fxnum::is_neg() const
2994{
2995 SC_FXNUM_OBSERVER_READ_(*this)
2996 return m_rep->is_neg();
2997}
2998
2999inline bool
3000sc_fxnum::is_zero() const
3001{
3002 SC_FXNUM_OBSERVER_READ_(*this)
3003 return m_rep->is_zero();
3004}
3005
3006// internal use only;
3007inline bool
3008sc_fxnum::is_normal() const
3009{
3010 SC_FXNUM_OBSERVER_READ_(*this)
3011 return m_rep->is_normal();
3012}
3013
3014inline bool
3015sc_fxnum::quantization_flag() const
3016{
3017 return m_q_flag;
3018}
3019
3020inline bool
3021sc_fxnum::overflow_flag() const
3022{
3023 return m_o_flag;
3024}
3025
3026
3027inline const sc_fxval
3028sc_fxnum::value() const
3029{
3030 SC_FXNUM_OBSERVER_READ_(*this)
3031 return sc_fxval(new scfx_rep(*m_rep));
3032}
3033
3034// query parameters
3035inline int
3036sc_fxnum::wl() const
3037{
3038 return m_params.wl();
3039}
3040
3041inline int
3042sc_fxnum::iwl() const
3043{
3044 return m_params.iwl();
3045}
3046
3047inline sc_q_mode
3048sc_fxnum::q_mode() const
3049{
3050 return m_params.q_mode();
3051}
3052
3053inline sc_o_mode
3054sc_fxnum::o_mode() const
3055{
3056 return m_params.o_mode();
3057}
3058
3059inline int
3060sc_fxnum::n_bits() const
3061{
3062 return m_params.n_bits();
3063}
3064
3065inline const sc_fxtype_params &
3066sc_fxnum::type_params() const
3067{
3068 return m_params.type_params();
3069}
3070
3071inline const sc_fxcast_switch &
3072sc_fxnum::cast_switch() const
3073{
3074 return m_params.cast_switch();
3075}
3076
3077// internal use only;
3078inline void
3079sc_fxnum::observer_read() const
3080{
3081 SC_FXNUM_OBSERVER_READ_(*this);
3082}
3083
3084// internal use only;
3085inline bool
3086sc_fxnum::get_bit(int i) const
3087{
3088 return m_rep->get_bit(i);
3089}
3090
3091// protected methods and friend functions
3092inline bool
3093sc_fxnum::set_bit(int i, bool high)
3094{
3095 if (high)
3096 return m_rep->set(i, m_params);
3097 else
3098 return m_rep->clear(i, m_params);
3099}
3100
3101inline bool
3102sc_fxnum::get_slice(int i, int j, sc_bv_base &bv) const
3103{
3104 return m_rep->get_slice(i, j, m_params, bv);
3105}
3106
3107inline bool
3108sc_fxnum::set_slice(int i, int j, const sc_bv_base &bv)
3109{
3110 return m_rep->set_slice(i, j, m_params, bv);
3111}
3112
3113inline ::std::ostream &
3114operator << (::std::ostream &os, const sc_fxnum &a)
3115{
3116 a.print(os);
3117 return os;
3118}
3119
3120inline ::std::istream &
3121operator >> (::std::istream &is, sc_fxnum &a)
3122{
3123 a.scan(is);
3124 return is;
3125}
3126
3127
3128// ----------------------------------------------------------------------------
3129// CLASS : sc_fxnum_fast
3130//
3131// Base class for the fixed-point types; limited precision.
3132// ----------------------------------------------------------------------------
3133
3134inline sc_fxnum_fast_observer *
3135sc_fxnum_fast::observer() const
3136{
3137 return m_observer;
3138}
3139
3140
3141// constructors
3142inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxtype_params &type_params_,
3143 sc_enc enc_,
3144 const sc_fxcast_switch &cast_sw,
3145 sc_fxnum_fast_observer *observer_) :
3146 m_val(0.0), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3147 m_o_flag(false), m_observer(observer_)
3148{
3149 SC_FXNUM_FAST_OBSERVER_DEFAULT_
3150 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3151}
3152
3153inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxnum_fast &a,
3154 const sc_fxtype_params &type_params_,
3155 sc_enc enc_,
3156 const sc_fxcast_switch &cast_sw,
3157 sc_fxnum_fast_observer *observer_) :
3158 m_val(a.m_val), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3159 m_o_flag(false), m_observer(observer_)
3160{
3161 SC_FXNUM_FAST_OBSERVER_DEFAULT_
3162 SC_FXNUM_FAST_OBSERVER_READ_(a)
3163 cast();
3164 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3165 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3166}
3167
3168#define DEFN_CTOR_T(tp, arg) \
3169inline sc_fxnum_fast::sc_fxnum_fast( \
3170 tp a, const sc_fxtype_params &type_params_, sc_enc enc_, \
3171 const sc_fxcast_switch &cast_sw, \
3172 sc_fxnum_fast_observer *observer_) : \
3173 m_val(arg), m_params(type_params_, enc_, cast_sw), m_q_flag(false), \
3174 m_o_flag(false), m_observer(observer_) \
3175{ \
3176 SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
3177 cast(); \
3178 SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \
3179 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3180}
3181
3182#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, static_cast<double>(a))
3183#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, sc_fxval_fast::from_string(a))
3184#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
3185
3186DEFN_CTOR_T_A(int)
3187DEFN_CTOR_T_A(unsigned int)
3188DEFN_CTOR_T_A(long)
3189DEFN_CTOR_T_A(unsigned long)
3190DEFN_CTOR_T_A(float)
3191DEFN_CTOR_T_A(double)
3192DEFN_CTOR_T_B(const char *)
3193DEFN_CTOR_T_C(const sc_fxval &)
3194DEFN_CTOR_T_C(const sc_fxval_fast &)
3195DEFN_CTOR_T_C(const sc_fxnum &)
3196
3197DEFN_CTOR_T_A(int64)
3198DEFN_CTOR_T_A(uint64)
3199DEFN_CTOR_T_C(const sc_int_base &)
3200DEFN_CTOR_T_C(const sc_uint_base &)
3201DEFN_CTOR_T_C(const sc_signed &)
3202DEFN_CTOR_T_C(const sc_unsigned &)
3203
3204#undef DEFN_CTOR_T
3205#undef DEFN_CTOR_T_A
3206#undef DEFN_CTOR_T_B
3207#undef DEFN_CTOR_T_C
3208#undef DEFN_CTOR_T_D
3209#undef DEFN_CTOR_T_E
3210
3211inline sc_fxnum_fast::~sc_fxnum_fast()
3212{
3213 SC_FXNUM_FAST_OBSERVER_DESTRUCT_(*this)
3214}
3215
3216// internal use only;
3217inline double
3218sc_fxnum_fast::get_val() const
3219{
3220 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3221 return m_val;
3222}
3223
3224// unary operators
3225inline const sc_fxval_fast
3226sc_fxnum_fast::operator - () const
3227{
3228 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3229 return sc_fxval_fast(- m_val);
3230}
3231
3232inline const sc_fxval_fast
3233sc_fxnum_fast::operator + () const
3234{
3235 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3236 return sc_fxval_fast(m_val);
3237}
3238
3239// unary functions
3240inline void
3241neg(sc_fxval_fast &c, const sc_fxnum_fast &a)
3242{
3243 SC_FXNUM_FAST_OBSERVER_READ_(a)
3244 c.set_val(- a.m_val);
3245}
3246
3247inline void
3248neg(sc_fxnum_fast &c, const sc_fxnum_fast &a)
3249{
3250 SC_FXNUM_FAST_OBSERVER_READ_(a)
3251 c.m_val = - a.m_val;
3252 c.cast();
3253 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3254}
3255
3256// binary operators
3257#define DEFN_BIN_OP_T(op, tp) \
3258inline const sc_fxval_fast \
3259operator op (const sc_fxnum_fast &a, tp b) \
3260{ \
3261 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3262 sc_fxval_fast tmp(b); \
3263 return sc_fxval_fast(a.m_val op tmp.get_val()); \
3264} \
3265 \
3266inline const sc_fxval_fast \
3267operator op (tp a, const sc_fxnum_fast &b) \
3268{ \
3269 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3270 sc_fxval_fast tmp(a); \
3271 return sc_fxval_fast(tmp.get_val() op b.m_val); \
3272}
3273
3274#define DEFN_BIN_OP_OTHER(op) \
3275DEFN_BIN_OP_T(op, int64) \
3276DEFN_BIN_OP_T(op, uint64) \
3277DEFN_BIN_OP_T(op, const sc_int_base &) \
3278DEFN_BIN_OP_T(op, const sc_uint_base &) \
3279DEFN_BIN_OP_T(op, const sc_signed &) \
3280DEFN_BIN_OP_T(op, const sc_unsigned &)
3281
3282#define DEFN_BIN_OP(op, dummy) \
3283inline const sc_fxval_fast \
3284operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3285{ \
3286 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3287 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3288 return sc_fxval_fast(a.m_val op b.m_val); \
3289} \
3290 \
3291inline const sc_fxval_fast \
3292operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3293{ \
3294 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3295 return sc_fxval_fast(a.m_val op b.get_val()); \
3296} \
3297 \
3298inline const sc_fxval_fast \
3299operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3300{ \
3301 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3302 return sc_fxval_fast(a.get_val() op b.m_val); \
3303} \
3304 \
3305DEFN_BIN_OP_T(op, int) \
3306DEFN_BIN_OP_T(op, unsigned int) \
3307DEFN_BIN_OP_T(op, long) \
3308DEFN_BIN_OP_T(op, unsigned long) \
3309DEFN_BIN_OP_T(op, float) \
3310DEFN_BIN_OP_T(op, double) \
3311DEFN_BIN_OP_T(op, const char *) \
3312DEFN_BIN_OP_OTHER(op)
3313
3314DEFN_BIN_OP(*, mult)
3315DEFN_BIN_OP(+, add)
3316DEFN_BIN_OP(-, sub)
3317//DEFN_BIN_OP(/, div)
3318inline const sc_fxval_fast
3319operator / (const sc_fxnum_fast &a, const sc_fxnum_fast &b)
3320{
3321 SC_FXNUM_FAST_OBSERVER_READ_(a)
3322 SC_FXNUM_FAST_OBSERVER_READ_(b)
3323 return sc_fxval_fast(a.m_val / b.m_val);
3324}
3325
3326inline const sc_fxval_fast
3327operator / (const sc_fxnum_fast &a, const sc_fxval_fast &b)
3328{
3329 SC_FXNUM_FAST_OBSERVER_READ_(a)
3330 return sc_fxval_fast(a.m_val / b.get_val());
3331}
3332
3333inline const sc_fxval_fast
3334operator / (const sc_fxval_fast &a, const sc_fxnum_fast &b)
3335{
3336 SC_FXNUM_FAST_OBSERVER_READ_(b)
3337 return sc_fxval_fast(a.get_val() / b.m_val);
3338}
3339
3340DEFN_BIN_OP_T(/, int)
3341DEFN_BIN_OP_T(/, unsigned int)
3342DEFN_BIN_OP_T(/, long)
3343DEFN_BIN_OP_T(/, unsigned long)
3344DEFN_BIN_OP_T(/, float)
3345DEFN_BIN_OP_T(/, double)
3346DEFN_BIN_OP_T(/, const char *)
3347//DEFN_BIN_OP_OTHER(/)
3348
3349DEFN_BIN_OP_T(/, int64)
3350DEFN_BIN_OP_T(/, uint64)
3351DEFN_BIN_OP_T(/, const sc_int_base &)
3352DEFN_BIN_OP_T(/, const sc_uint_base &)
3353DEFN_BIN_OP_T(/, const sc_signed &)
3354DEFN_BIN_OP_T(/, const sc_unsigned &)
3355
3356#undef DEFN_BIN_OP_T
3357#undef DEFN_BIN_OP_OTHER
3358#undef DEFN_BIN_OP
3359
3360inline const sc_fxval_fast
3361operator << (const sc_fxnum_fast &a, int b)
3362{
3363 SC_FXNUM_FAST_OBSERVER_READ_(a)
3364 return sc_fxval_fast(a.m_val *scfx_pow2(b));
3365}
3366
3367inline const sc_fxval_fast
3368operator >> (const sc_fxnum_fast &a, int b)
3369{
3370 SC_FXNUM_FAST_OBSERVER_READ_(a)
3371 return sc_fxval_fast(a.m_val *scfx_pow2(-b));
3372}
3373
3374// binary functions
3375#define DEFN_BIN_FNC_T(fnc, op, tp) \
3376inline void \
3377fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, tp b) \
3378{ \
3379 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3380 sc_fxval_fast tmp(b); \
3381 c.set_val(a.m_val op tmp.get_val()); \
3382} \
3383 \
3384inline void \
3385fnc (sc_fxval_fast &c, tp a, const sc_fxnum_fast &b) \
3386{ \
3387 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3388 sc_fxval_fast tmp(a); \
3389 c.set_val(tmp.get_val() op b.m_val); \
3390} \
3391 \
3392inline void \
3393fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, tp b) \
3394{ \
3395 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3396 sc_fxval_fast tmp(b); \
3397 c.m_val = a.m_val op tmp.get_val(); \
3398 c.cast(); \
3399 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3400} \
3401 \
3402inline void \
3403fnc (sc_fxnum_fast &c, tp a, const sc_fxnum_fast &b) \
3404{ \
3405 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3406 sc_fxval_fast tmp(a); \
3407 c.m_val = tmp.get_val() op b.m_val; \
3408 c.cast(); \
3409 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3410}
3411
3412#define DEFN_BIN_FNC_OTHER(fnc, op) \
3413DEFN_BIN_FNC_T(fnc, op, int64) \
3414DEFN_BIN_FNC_T(fnc, op, uint64) \
3415DEFN_BIN_FNC_T(fnc, op, const sc_int_base &) \
3416DEFN_BIN_FNC_T(fnc, op, const sc_uint_base &) \
3417DEFN_BIN_FNC_T(fnc, op, const sc_signed &) \
3418DEFN_BIN_FNC_T(fnc, op, const sc_unsigned &)
3419
3420#define DEFN_BIN_FNC(fnc, op) \
3421inline void \
3422fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3423{ \
3424 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3425 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3426 c.set_val(a.m_val op b.m_val); \
3427} \
3428 \
3429inline void \
3430fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3431{ \
3432 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3433 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3434 c.m_val = a.m_val op b.m_val; \
3435 c.cast(); \
3436 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3437} \
3438 \
3439inline void \
3440fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3441{ \
3442 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3443 c.set_val(a.m_val op b.get_val()); \
3444} \
3445 \
3446inline void \
3447fnc (sc_fxval_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3448{ \
3449 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3450 c.set_val(a.get_val() op b.m_val); \
3451} \
3452 \
3453inline void \
3454fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3455{ \
3456 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3457 c.m_val = a.m_val op b.get_val(); \
3458 c.cast(); \
3459 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3460} \
3461 \
3462inline void \
3463fnc (sc_fxnum_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3464{ \
3465 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3466 c.m_val = a.get_val() op b.m_val; \
3467 c.cast(); \
3468 SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3469} \
3470 \
3471DEFN_BIN_FNC_T(fnc, op, int) \
3472DEFN_BIN_FNC_T(fnc, op, unsigned int) \
3473DEFN_BIN_FNC_T(fnc, op, long) \
3474DEFN_BIN_FNC_T(fnc, op, unsigned long) \
3475DEFN_BIN_FNC_T(fnc, op, float) \
3476DEFN_BIN_FNC_T(fnc, op, double) \
3477DEFN_BIN_FNC_T(fnc, op, const char *) \
3478DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
3479DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &) \
3480DEFN_BIN_FNC_OTHER(fnc, op)
3481
3482DEFN_BIN_FNC(mult, *)
3483DEFN_BIN_FNC(div, /)
3484DEFN_BIN_FNC(add, +)
3485DEFN_BIN_FNC(sub, -)
3486
3487#undef DEFN_BIN_FNC_T
3488#undef DEFN_BIN_FNC_OTHER
3489#undef DEFN_BIN_FNC
3490
3491inline void
3492lshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3493{
3494 SC_FXNUM_FAST_OBSERVER_READ_(a)
3495 c.set_val(a.m_val * scfx_pow2(b));
3496}
3497
3498inline void
3499rshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3500{
3501 SC_FXNUM_FAST_OBSERVER_READ_(a)
3502 c.set_val(a.m_val * scfx_pow2(-b));
3503}
3504
3505inline void
3506lshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3507{
3508 SC_FXNUM_FAST_OBSERVER_READ_(a)
3509 c.m_val = a.m_val * scfx_pow2(b);
3510 c.cast();
3511 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3512}
3513
3514inline void
3515rshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3516{
3517 SC_FXNUM_FAST_OBSERVER_READ_(a)
3518 c.m_val = a.m_val * scfx_pow2(-b);
3519 c.cast();
3520 SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3521}
3522
3523// relational (including equality) operators
3524#define DEFN_REL_OP_T(op, tp) \
3525inline bool \
3526operator op (const sc_fxnum_fast &a, tp b) \
3527{ \
3528 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3529 sc_fxval_fast tmp(b); \
3530 return (a.m_val op tmp.get_val()); \
3531} \
3532 \
3533inline bool \
3534operator op (tp a, const sc_fxnum_fast &b) \
3535{ \
3536 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3537 sc_fxval_fast tmp(a); \
3538 return (tmp.get_val() op b.m_val); \
3539}
3540
3541#define DEFN_REL_OP_OTHER(op) \
3542DEFN_REL_OP_T(op, int64) \
3543DEFN_REL_OP_T(op, uint64) \
3544DEFN_REL_OP_T(op, const sc_int_base &) \
3545DEFN_REL_OP_T(op, const sc_uint_base &) \
3546DEFN_REL_OP_T(op, const sc_signed &) \
3547DEFN_REL_OP_T(op, const sc_unsigned &)
3548
3549#define DEFN_REL_OP(op) \
3550inline bool \
3551operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3552{ \
3553 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3554 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3555 return (a.m_val op b.m_val); \
3556} \
3557 \
3558inline bool \
3559operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3560{ \
3561 SC_FXNUM_FAST_OBSERVER_READ_(a) \
3562 return (a.m_val op b.get_val()); \
3563} \
3564 \
3565inline bool \
3566operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3567{ \
3568 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3569 return (a.get_val() op b.m_val); \
3570} \
3571 \
3572DEFN_REL_OP_T(op, int) \
3573DEFN_REL_OP_T(op, unsigned int) \
3574DEFN_REL_OP_T(op, long) \
3575DEFN_REL_OP_T(op, unsigned long) \
3576DEFN_REL_OP_T(op, float) \
3577DEFN_REL_OP_T(op, double) \
3578DEFN_REL_OP_T(op, const char *) \
3579DEFN_REL_OP_OTHER(op)
3580
3581DEFN_REL_OP(<)
3582DEFN_REL_OP(<=)
3583DEFN_REL_OP(>)
3584DEFN_REL_OP(>=)
3585DEFN_REL_OP(==)
3586DEFN_REL_OP(!=)
3587
3588#undef DEFN_REL_OP_T
3589#undef DEFN_REL_OP_OTHER
3590#undef DEFN_REL_OP
3591
3592// assignment operators
3593
3594inline sc_fxnum_fast &
3595sc_fxnum_fast::operator = (const sc_fxnum_fast &a)
3596{
3597 if (&a != this) {
3598 SC_FXNUM_FAST_OBSERVER_READ_(a)
3599 m_val = a.m_val;
3600 cast();
3601 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3602 }
3603 return *this;
3604}
3605
3606inline sc_fxnum_fast &
3607sc_fxnum_fast::operator = (const sc_fxval_fast &a)
3608{
3609 m_val = a.get_val();
3610 cast();
3611 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3612 return *this;
3613}
3614
3615#define DEFN_ASN_OP_T(tp) \
3616inline sc_fxnum_fast & \
3617sc_fxnum_fast::operator = (tp a) \
3618{ \
3619 sc_fxval_fast tmp(a); \
3620 m_val = tmp.get_val(); \
3621 cast(); \
3622 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3623 return *this; \
3624}
3625
3626DEFN_ASN_OP_T(int)
3627DEFN_ASN_OP_T(unsigned int)
3628DEFN_ASN_OP_T(long)
3629DEFN_ASN_OP_T(unsigned long)
3630DEFN_ASN_OP_T(float)
3631DEFN_ASN_OP_T(double)
3632DEFN_ASN_OP_T(const char *)
3633DEFN_ASN_OP_T(const sc_fxval &)
3634DEFN_ASN_OP_T(const sc_fxnum &)
3635
3636DEFN_ASN_OP_T(int64)
3637DEFN_ASN_OP_T(uint64)
3638DEFN_ASN_OP_T(const sc_int_base &)
3639DEFN_ASN_OP_T(const sc_uint_base &)
3640DEFN_ASN_OP_T(const sc_signed &)
3641DEFN_ASN_OP_T(const sc_unsigned &)
3642
3643#undef DEFN_ASN_OP_T
3644
3645#define DEFN_ASN_OP_T(op, tp) \
3646inline sc_fxnum_fast & \
3647sc_fxnum_fast::operator op (tp b) \
3648{ \
3649 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3650 sc_fxval_fast tmp(b); \
3651 m_val op tmp.get_val(); \
3652 cast(); \
3653 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3654 return *this; \
3655}
3656
3657#define DEFN_ASN_OP_OTHER(op) \
3658DEFN_ASN_OP_T(op, int64) \
3659DEFN_ASN_OP_T(op, uint64) \
3660DEFN_ASN_OP_T(op, const sc_int_base &) \
3661DEFN_ASN_OP_T(op, const sc_uint_base &) \
3662DEFN_ASN_OP_T(op, const sc_signed &) \
3663DEFN_ASN_OP_T(op, const sc_unsigned &)
3664
3665#define DEFN_ASN_OP(op) \
3666inline sc_fxnum_fast & \
3667sc_fxnum_fast::operator op (const sc_fxnum_fast &b) \
3668{ \
3669 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3670 SC_FXNUM_FAST_OBSERVER_READ_(b) \
3671 m_val op b.m_val; \
3672 cast(); \
3673 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3674 return *this; \
3675} \
3676 \
3677inline sc_fxnum_fast & \
3678sc_fxnum_fast::operator op (const sc_fxval_fast &b) \
3679{ \
3680 SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3681 m_val op b.get_val(); \
3682 cast(); \
3683 SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3684 return *this; \
3685} \
3686 \
3687DEFN_ASN_OP_T(op, int) \
3688DEFN_ASN_OP_T(op, unsigned int) \
3689DEFN_ASN_OP_T(op, long) \
3690DEFN_ASN_OP_T(op, unsigned long) \
3691DEFN_ASN_OP_T(op, float) \
3692DEFN_ASN_OP_T(op, double) \
3693DEFN_ASN_OP_T(op, const char *) \
3694DEFN_ASN_OP_T(op, const sc_fxval &) \
3695DEFN_ASN_OP_T(op, const sc_fxnum &) \
3696DEFN_ASN_OP_OTHER(op)
3697
3698DEFN_ASN_OP(*=)
3699DEFN_ASN_OP(/=)
3700DEFN_ASN_OP(+=)
3701DEFN_ASN_OP(-=)
3702
3703#undef DEFN_ASN_OP_T
3704#undef DEFN_ASN_OP_OTHER
3705#undef DEFN_ASN_OP
3706
3707inline sc_fxnum_fast &
3708sc_fxnum_fast::operator <<= (int b)
3709{
3710 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3711 m_val *= scfx_pow2(b);
3712 cast();
3713 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3714 return *this;
3715}
3716
3717inline sc_fxnum_fast &
3718sc_fxnum_fast::operator >>= (int b)
3719{
3720 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3721 m_val *= scfx_pow2(-b);
3722 cast();
3723 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3724 return *this;
3725}
3726
3727// auto-increment and auto-decrement
3728inline const sc_fxval_fast
3729sc_fxnum_fast::operator ++ (int)
3730{
3731 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3732 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3733 double c = m_val;
3734 m_val = m_val + 1;
3735 cast();
3736 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3737 return sc_fxval_fast(c);
3738}
3739
3740inline const sc_fxval_fast
3741sc_fxnum_fast::operator -- (int)
3742{
3743 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3744 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3745 double c = m_val;
3746 m_val = m_val - 1;
3747 cast();
3748 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3749 return sc_fxval_fast(c);
3750}
3751
3752inline sc_fxnum_fast &
3753sc_fxnum_fast::operator ++ ()
3754{
3755 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3756 m_val = m_val + 1;
3757 cast();
3758 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3759 return *this;
3760}
3761
3762inline sc_fxnum_fast &
3763sc_fxnum_fast::operator -- ()
3764{
3765 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3766 m_val = m_val - 1;
3767 cast();
3768 SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3769 return *this;
3770}
3771
3772// bit selection
3773inline const sc_fxnum_fast_bitref
3774sc_fxnum_fast::operator [] (int i) const
3775{
3776 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3777 return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3778 i - m_params.fwl());
3779}
3780
3781inline sc_fxnum_fast_bitref
3782sc_fxnum_fast::operator [] (int i)
3783{
3784 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3785 return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3786}
3787
3788inline const sc_fxnum_fast_bitref
3789sc_fxnum_fast::bit(int i) const
3790{
3791 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3792 return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3793 i - m_params.fwl());
3794}
3795
3796inline sc_fxnum_fast_bitref
3797sc_fxnum_fast::bit(int i)
3798{
3799 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3800 return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3801}
3802
3803// part selection
3804inline const sc_fxnum_fast_subref
3805sc_fxnum_fast::operator () (int i, int j) const
3806{
3807 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3808 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3809
3810 return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3811 i - m_params.fwl(), j - m_params.fwl());
3812}
3813
3814inline sc_fxnum_fast_subref
3815sc_fxnum_fast::operator () (int i, int j)
3816{
3817 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3818 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3819
3820 return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3821}
3822
3823inline const sc_fxnum_fast_subref
3824sc_fxnum_fast::range(int i, int j) const
3825{
3826 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3827 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3828
3829 return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3830 i - m_params.fwl(), j - m_params.fwl());
3831}
3832
3833inline sc_fxnum_fast_subref
3834sc_fxnum_fast::range(int i, int j)
3835{
3836 SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3837 SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3838
3839 return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3840}
3841
3842inline const sc_fxnum_fast_subref
3843sc_fxnum_fast::operator () () const
3844{
3845 return this->operator () (m_params.wl() - 1, 0);
3846}
3847
3848inline sc_fxnum_fast_subref
3849sc_fxnum_fast::operator () ()
3850{
3851 return this->operator () (m_params.wl() - 1, 0);
3852}
3853
3854inline const sc_fxnum_fast_subref
3855sc_fxnum_fast::range() const
3856{
3857 return this->range(m_params.wl() - 1, 0);
3858}
3859
3860inline sc_fxnum_fast_subref
3861sc_fxnum_fast::range()
3862{
3863 return this->range(m_params.wl() - 1, 0);
3864}
3865
3866// implicit conversion
3867inline sc_fxnum_fast::operator double() const
3868{
3869 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3870 return m_val;
3871}
3872
3873// explicit conversion to primitive types
3874inline short
3875sc_fxnum_fast::to_short() const
3876{
3877 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3878 return static_cast<short>(to_uint64());
3879}
3880
3881inline unsigned short
3882sc_fxnum_fast::to_ushort() const
3883{
3884 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3885 return static_cast<unsigned short>(to_uint64());
3886}
3887
3888inline int
3889sc_fxnum_fast::to_int() const
3890{
3891 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3892 return static_cast<int>(to_uint64());
3893}
3894
3895inline int64
3896sc_fxnum_fast::to_int64() const
3897{
3898 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3899 return static_cast<int64>(to_uint64());
3900}
3901
3902inline unsigned int
3903sc_fxnum_fast::to_uint() const
3904{
3905 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3906 return static_cast<unsigned int>(to_uint64());
3907}
3908
3909inline uint64
3910sc_fxnum_fast::to_uint64() const
3911{
3912 // SC_FXNUM_FAST_OBSERVER_READ_ in is_normal
3913 if (!is_normal()) {
3914 return 0;
3915 }
3916
3917 int exponent;
3918 double mantissa_dbl = frexp(m_val, &exponent);
3919
3920 uint64 mantissa = static_cast<uint64>(fabs(mantissa_dbl) *
3921 (UINT64_ONE << 53));
3922 exponent -= 53;
3923
3924 if (!(-64 < exponent && exponent < 64)) {
3925 return 0;
3926 }
3927
3928 mantissa = exponent >= 0 ? mantissa << exponent : mantissa >> -exponent;
3929 return mantissa_dbl >= 0 ? mantissa : -mantissa;
3930}
3931
3932inline long
3933sc_fxnum_fast::to_long() const
3934{
3935 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3936 return static_cast<long>(to_uint64());
3937}
3938
3939inline unsigned long
3940sc_fxnum_fast::to_ulong() const
3941{
3942 // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3943 return static_cast<unsigned long>(to_uint64());
3944}
3945
3946inline float
3947sc_fxnum_fast::to_float() const
3948{
3949 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3950 return static_cast<float>(m_val);
3951}
3952
3953inline double
3954sc_fxnum_fast::to_double() const
3955{
3956 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3957 return m_val;
3958}
3959
3960// query value
3961inline bool
3962sc_fxnum_fast::is_neg() const
3963{
3964 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3965 scfx_ieee_double id(m_val);
3966 return (id.negative() != 0);
3967}
3968
3969inline bool
3970sc_fxnum_fast::is_zero() const
3971{
3972 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3973 scfx_ieee_double id(m_val);
3974 return id.is_zero();
3975}
3976
3977// internal use only;
3978inline bool
3979sc_fxnum_fast::is_normal() const
3980{
3981 SC_FXNUM_FAST_OBSERVER_READ_(*this)
3982 scfx_ieee_double id(m_val);
3983 return (id.is_normal() || id.is_subnormal() || id.is_zero());
3984}
3985
3986inline bool
3987sc_fxnum_fast::quantization_flag() const
3988{
3989 return m_q_flag;
3990}
3991
3992inline bool
3993sc_fxnum_fast::overflow_flag() const
3994{
3995 return m_o_flag;
3996}
3997
3998inline const sc_fxval_fast
3999sc_fxnum_fast::value() const
4000{
4001 SC_FXNUM_FAST_OBSERVER_READ_(*this)
4002 return sc_fxval_fast(m_val);
4003}
4004
4005// query parameters
4006inline int
4007sc_fxnum_fast::wl() const
4008{
4009 return m_params.wl();
4010}
4011
4012inline int
4013sc_fxnum_fast::iwl() const
4014{
4015 return m_params.iwl();
4016}
4017
4018inline sc_q_mode
4019sc_fxnum_fast::q_mode() const
4020{
4021 return m_params.q_mode();
4022}
4023
4024inline sc_o_mode
4025sc_fxnum_fast::o_mode() const
4026{
4027 return m_params.o_mode();
4028}
4029
4030inline int
4031sc_fxnum_fast::n_bits() const
4032{
4033 return m_params.n_bits();
4034}
4035
4036inline const sc_fxtype_params &
4037sc_fxnum_fast::type_params() const
4038{
4039 return m_params.type_params();
4040}
4041
4042inline const sc_fxcast_switch &
4043sc_fxnum_fast::cast_switch() const
4044{
4045 return m_params.cast_switch();
4046}
4047
4048// internal use only;
4049inline void
4050sc_fxnum_fast::observer_read() const
4051{
4052 SC_FXNUM_FAST_OBSERVER_READ_(*this);
4053}
4054
4055inline ::std::ostream &
4056operator << (::std::ostream &os, const sc_fxnum_fast &a)
4057{
4058 a.print(os);
4059 return os;
4060}
4061
4062inline ::std::istream &
4063operator >> (::std::istream &is, sc_fxnum_fast &a)
4064{
4065 a.scan(is);
4066 return is;
4067}
4068
4069
4070// ----------------------------------------------------------------------------
4071// CLASS : sc_fxval
4072//
4073// Fixed-point value type; arbitrary precision.
4074// ----------------------------------------------------------------------------
4075
4076// public constructors
4077inline sc_fxval::sc_fxval(const sc_fxnum &a, sc_fxval_observer *observer_) :
4078 m_rep(new scfx_rep(*a.get_rep())), m_observer(observer_)
4079{
4080 SC_FXVAL_OBSERVER_DEFAULT_
4081 SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4082 SC_FXVAL_OBSERVER_WRITE_(*this)
4083}
4084
4085inline sc_fxval::sc_fxval(const sc_fxnum_fast &a,
4086 sc_fxval_observer *observer_) :
4087 m_rep(new scfx_rep(a.to_double())), m_observer(observer_)
4088{
4089 SC_FXVAL_OBSERVER_DEFAULT_
4090 SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4091 SC_FXVAL_OBSERVER_WRITE_(*this)
4092}
4093
4094// binary operators
4095#define DEFN_BIN_OP_T(op, fnc, tp) \
4096inline const sc_fxval \
4097operator op (const sc_fxval &a, tp b) \
4098{ \
4099 SC_FXVAL_OBSERVER_READ_(a) \
4100 sc_fxval tmp(b); \
4101 return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep)); \
4102} \
4103 \
4104inline const sc_fxval \
4105operator op (tp a, const sc_fxval &b) \
4106{ \
4107 SC_FXVAL_OBSERVER_READ_(b) \
4108 sc_fxval tmp(a); \
4109 return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep)); \
4110}
4111
4112#define DEFN_BIN_OP(op, fnc) \
4113DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &)
4114
4115DEFN_BIN_OP(*, mult)
4116DEFN_BIN_OP(+, add)
4117DEFN_BIN_OP(-, sub)
4118//DEFN_BIN_OP(/, div)
4119DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
4120
4121#undef DEFN_BIN_OP_T
4122#undef DEFN_BIN_OP
4123
4124
4125// binary functions
4126#define DEFN_BIN_FNC_T(fnc, tp) \
4127inline void \
4128fnc (sc_fxval &c, const sc_fxval &a, tp b) \
4129{ \
4130 SC_FXVAL_OBSERVER_READ_(a) \
4131 sc_fxval tmp(b); \
4132 delete c.m_rep; \
4133 c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep); \
4134 SC_FXVAL_OBSERVER_WRITE_(c) \
4135} \
4136 \
4137inline void \
4138fnc (sc_fxval &c, tp a, const sc_fxval &b) \
4139{ \
4140 SC_FXVAL_OBSERVER_READ_(b) \
4141 sc_fxval tmp(a); \
4142 delete c.m_rep; \
4143 c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep); \
4144 SC_FXVAL_OBSERVER_WRITE_(c) \
4145}
4146
4147#define DEFN_BIN_FNC(fnc) \
4148DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &)
4149
4150DEFN_BIN_FNC(mult)
4151DEFN_BIN_FNC(div)
4152DEFN_BIN_FNC(add)
4153DEFN_BIN_FNC(sub)
4154
4155#undef DEFN_BIN_FNC_T
4156#undef DEFN_BIN_FNC
4157
4158
4159// relational (including equality) operators
4160#define DEFN_REL_OP_T(op, ret, tp) \
4161inline bool \
4162operator op (const sc_fxval &a, tp b) \
4163{ \
4164 SC_FXVAL_OBSERVER_READ_(a) \
4165 sc_fxval tmp(b); \
4166 int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.m_rep); \
4167 return (ret); \
4168} \
4169 \
4170inline bool \
4171operator op (tp a, const sc_fxval &b) \
4172{ \
4173 SC_FXVAL_OBSERVER_READ_(b) \
4174 sc_fxval tmp(a); \
4175 int result = sc_dt::cmp_scfx_rep(*tmp.m_rep, *b.m_rep); \
4176 return (ret); \
4177}
4178
4179#define DEFN_REL_OP(op, ret) \
4180DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &)
4181
4182DEFN_REL_OP(<, result < 0)
4183DEFN_REL_OP(<=, result <= 0)
4184DEFN_REL_OP(>, result > 0 && result != 2)
4185DEFN_REL_OP(>=, result >= 0 && result != 2)
4186DEFN_REL_OP(==, result == 0)
4187DEFN_REL_OP(!=, result != 0)
4188
4189#undef DEFN_REL_OP_T
4190#undef DEFN_REL_OP
4191
4192// assignment operators
4193inline sc_fxval &
4194sc_fxval::operator = (const sc_fxnum &a)
4195{
4196 *m_rep = *a.get_rep();
4197 SC_FXVAL_OBSERVER_WRITE_(*this)
4198 return *this;
4199}
4200
4201#define DEFN_ASN_OP_T(tp) \
4202inline sc_fxval & \
4203sc_fxval::operator = (tp b) \
4204{ \
4205 sc_fxval tmp(b); \
4206 *m_rep = *tmp.m_rep; \
4207 SC_FXVAL_OBSERVER_WRITE_(*this) \
4208 return *this; \
4209}
4210
4211DEFN_ASN_OP_T(const sc_fxnum_fast &)
4212
4213#undef DEFN_ASN_OP_T
4214
4215#define DEFN_ASN_OP_T(op, fnc, tp) \
4216inline sc_fxval & \
4217sc_fxval::operator op (tp b) \
4218{ \
4219 SC_FXVAL_OBSERVER_READ_(*this) \
4220 sc_fxval tmp(b); \
4221 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.m_rep); \
4222 delete m_rep; \
4223 m_rep = new_rep; \
4224 SC_FXVAL_OBSERVER_WRITE_(*this) \
4225 return *this; \
4226}
4227
4228#define DEFN_ASN_OP(op, fnc) \
4229inline sc_fxval & \
4230sc_fxval::operator op (const sc_fxnum &b) \
4231{ \
4232 SC_FXVAL_OBSERVER_READ_(*this) \
4233 scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
4234 delete m_rep; \
4235 m_rep = new_rep; \
4236 SC_FXVAL_OBSERVER_WRITE_(*this) \
4237 return *this; \
4238} \
4239 \
4240DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &)
4241
4242DEFN_ASN_OP(*=, mult)
4243DEFN_ASN_OP(/=, div)
4244DEFN_ASN_OP(+=, add)
4245DEFN_ASN_OP(-=, sub)
4246
4247#undef DEFN_ASN_OP_T
4248#undef DEFN_ASN_OP
4249
4250
4251// ----------------------------------------------------------------------------
4252// CLASS : sc_fxval_fast
4253//
4254// Fixed-point value types; limited precision.
4255// ----------------------------------------------------------------------------
4256
4257// public constructors
4258
4259inline
4260sc_fxval_fast::sc_fxval_fast(const sc_fxnum &a,
4261 sc_fxval_fast_observer *observer_) :
4262 m_val(a.to_double()), m_observer(observer_)
4263{
4264 SC_FXVAL_FAST_OBSERVER_DEFAULT_
4265 SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4266 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4267}
4268
4269inline sc_fxval_fast::sc_fxval_fast(const sc_fxnum_fast &a,
4270 sc_fxval_fast_observer *observer_) :
4271 m_val(a.get_val()), m_observer(observer_)
4272{
4273 SC_FXVAL_FAST_OBSERVER_DEFAULT_
4274 SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4275 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4276}
4277
4278
4279// binary functions
4280#define DEFN_BIN_FNC_T(fnc, op, tp) \
4281inline void \
4282fnc (sc_fxval_fast &c, const sc_fxval_fast &a, tp b) \
4283{ \
4284 SC_FXVAL_FAST_OBSERVER_READ_(a) \
4285 sc_fxval_fast tmp(b); \
4286 c.m_val = a.m_val op tmp.m_val; \
4287 SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4288} \
4289 \
4290inline void \
4291fnc (sc_fxval_fast &c, tp a, const sc_fxval_fast &b) \
4292{ \
4293 SC_FXVAL_FAST_OBSERVER_READ_(b) \
4294 sc_fxval_fast tmp(a); \
4295 c.m_val = tmp.m_val op b.m_val; \
4296 SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4297}
4298
4299#define DEFN_BIN_FNC(fnc, op) \
4300DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
4301DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &)
4302
4303DEFN_BIN_FNC(mult, *)
4304DEFN_BIN_FNC(div, /)
4305DEFN_BIN_FNC(add, +)
4306DEFN_BIN_FNC(sub, -)
4307
4308#undef DEFN_BIN_FNC_T
4309#undef DEFN_BIN_FNC
4310
4311
4312// assignment operators
4313inline sc_fxval_fast &
4314sc_fxval_fast::operator = (const sc_fxnum_fast &a)
4315{
4316 m_val = a.get_val();
4317 SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4318 return *this;
4319}
4320
4321#define DEFN_ASN_OP_T(tp) \
4322inline sc_fxval_fast & \
4323sc_fxval_fast::operator = (tp a) \
4324{ \
4325 sc_fxval_fast tmp(a); \
4326 m_val = tmp.m_val; \
4327 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4328 return *this; \
4329}
4330
4331DEFN_ASN_OP_T(const sc_fxnum &)
4332
4333#undef DEFN_ASN_OP_T
4334
4335#define DEFN_ASN_OP_T(op, tp) \
4336inline sc_fxval_fast & \
4337sc_fxval_fast::operator op (tp b) \
4338{ \
4339 SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4340 sc_fxval_fast tmp(b); \
4341 m_val op tmp.m_val; \
4342 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4343 return *this; \
4344}
4345
4346#define DEFN_ASN_OP(op) \
4347inline sc_fxval_fast & \
4348sc_fxval_fast::operator op (const sc_fxnum_fast &b) \
4349{ \
4350 SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4351 m_val op b.get_val(); \
4352 SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4353 return *this; \
4354} \
4355 \
4356DEFN_ASN_OP_T(op, const sc_fxnum &)
4357
4358DEFN_ASN_OP(*=)
4359DEFN_ASN_OP(/=)
4360DEFN_ASN_OP(+=)
4361DEFN_ASN_OP(-=)
4362
4363#undef DEFN_ASN_OP_T
4364#undef DEFN_ASN_OP
4365
4366} // namespace sc_dt
4367
4368#endif // __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__