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