Deleted Added
sdiff udiff text old ( 12853:e23d6f09069a ) new ( 13245:c666c5d4996b )
full compact
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
70{
71
72class vcd_sc_fxnum_trace;
73class vcd_sc_fxnum_fast_trace;
74class wif_sc_fxnum_trace;
75class wif_sc_fxnum_fast_trace;
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
493 friend class sc_core::vcd_sc_fxnum_trace;
494 friend class sc_core::wif_sc_fxnum_trace;
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
854 friend class sc_core::vcd_sc_fxnum_fast_trace;
855 friend class sc_core::wif_sc_fxnum_fast_trace;
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__