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