sc_fxnum.hh revision 12853:e23d6f09069a
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__
4371