1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_fix.h -
23
24  Original Author: Martin Janssen, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38// $Log: sc_fix.h,v $
39// Revision 1.2  2011/01/19 18:57:40  acg
40//  Andy Goodrich: changes for IEEE_1666_2011.
41//
42// Revision 1.1.1.1  2006/12/15 20:20:04  acg
43// SystemC 2.3
44//
45// Revision 1.3  2006/01/13 18:53:57  acg
46// Andy Goodrich: added $Log command so that CVS comments are reproduced in
47// the source.
48//
49
50#ifndef __SYSTEMC_EXT_DT_FX_SC_FIX_HH__
51#define __SYSTEMC_EXT_DT_FX_SC_FIX_HH__
52
53#include "sc_fxnum.hh"
54
55namespace sc_dt
56{
57
58// classes defined in this module
59class sc_fix;
60class sc_fix_fast;
61
62
63// ----------------------------------------------------------------------------
64//  CLASS : sc_fix
65//
66//  "Unconstrained" signed fixed-point class; arbitrary precision.
67// ----------------------------------------------------------------------------
68
69class sc_fix : public sc_fxnum
70{
71  public:
72    // constructors
73    explicit sc_fix(sc_fxnum_observer * =0);
74    sc_fix(int, int, sc_fxnum_observer * =0);
75    sc_fix(sc_q_mode, sc_o_mode, sc_fxnum_observer * =0);
76    sc_fix(sc_q_mode, sc_o_mode, int, sc_fxnum_observer * =0);
77    sc_fix(int, int, sc_q_mode, sc_o_mode, sc_fxnum_observer * =0);
78    sc_fix(int, int, sc_q_mode, sc_o_mode, int, sc_fxnum_observer * =0);
79    explicit sc_fix(const sc_fxcast_switch &, sc_fxnum_observer * =0);
80    sc_fix(int, int, const sc_fxcast_switch &, sc_fxnum_observer * =0);
81    sc_fix(sc_q_mode, sc_o_mode, const sc_fxcast_switch &,
82           sc_fxnum_observer * =0);
83    sc_fix(sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &,
84           sc_fxnum_observer * =0);
85    sc_fix(int, int, sc_q_mode, sc_o_mode, const sc_fxcast_switch &,
86           sc_fxnum_observer * =0);
87    sc_fix(int, int, sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &,
88           sc_fxnum_observer * =0);
89    explicit sc_fix(const sc_fxtype_params &, sc_fxnum_observer * =0);
90    sc_fix(const sc_fxtype_params &, const sc_fxcast_switch &,
91           sc_fxnum_observer * =0);
92
93#define DECL_CTORS_T(tp) \
94    sc_fix(tp, int, int, sc_fxnum_observer * =0); \
95    sc_fix(tp, sc_q_mode, sc_o_mode, sc_fxnum_observer * =0); \
96    sc_fix(tp, sc_q_mode, sc_o_mode, int, sc_fxnum_observer * =0); \
97    sc_fix(tp, int, int, sc_q_mode, sc_o_mode, sc_fxnum_observer * =0); \
98    sc_fix(tp, int, int, sc_q_mode, sc_o_mode, int, sc_fxnum_observer * =0); \
99    sc_fix(tp, const sc_fxcast_switch &, sc_fxnum_observer * =0); \
100    sc_fix(tp, int, int, const sc_fxcast_switch &, sc_fxnum_observer * =0); \
101    sc_fix(tp, sc_q_mode, sc_o_mode, const sc_fxcast_switch &, \
102           sc_fxnum_observer * =0); \
103    sc_fix(tp, sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &, \
104           sc_fxnum_observer * =0); \
105    sc_fix(tp, int, int, sc_q_mode, sc_o_mode, const sc_fxcast_switch &, \
106           sc_fxnum_observer * =0); \
107    sc_fix(tp, int, int, sc_q_mode, sc_o_mode, int, \
108           const sc_fxcast_switch &, sc_fxnum_observer * =0); \
109    sc_fix(tp, const sc_fxtype_params &, sc_fxnum_observer * =0); \
110    sc_fix(tp, const sc_fxtype_params &, const sc_fxcast_switch &, \
111           sc_fxnum_observer * =0);
112
113#define DECL_CTORS_T_A(tp) \
114    sc_fix(tp, sc_fxnum_observer * =0); \
115    DECL_CTORS_T(tp)
116
117#define DECL_CTORS_T_B(tp) \
118    explicit sc_fix(tp, sc_fxnum_observer * =0); \
119    DECL_CTORS_T(tp)
120
121    DECL_CTORS_T_A(int)
122    DECL_CTORS_T_A(unsigned int)
123    DECL_CTORS_T_A(long)
124    DECL_CTORS_T_A(unsigned long)
125    DECL_CTORS_T_A(float)
126    DECL_CTORS_T_A(double)
127    DECL_CTORS_T_A(const char *)
128    DECL_CTORS_T_A(const sc_fxval &)
129    DECL_CTORS_T_A(const sc_fxval_fast &)
130    DECL_CTORS_T_A(const sc_fxnum &)
131    DECL_CTORS_T_A(const sc_fxnum_fast &)
132
133    DECL_CTORS_T_B(int64)
134    DECL_CTORS_T_B(uint64)
135    DECL_CTORS_T_B(const sc_int_base &)
136    DECL_CTORS_T_B(const sc_uint_base &)
137    DECL_CTORS_T_B(const sc_signed &)
138    DECL_CTORS_T_B(const sc_unsigned &)
139
140#undef DECL_CTORS_T
141#undef DECL_CTORS_T_A
142#undef DECL_CTORS_T_B
143
144    // copy constructor
145    sc_fix(const sc_fix &);
146
147    // unary bitwise operators
148    const sc_fix operator ~ () const;
149
150    // unary bitwise functions
151    friend void b_not(sc_fix &, const sc_fix &);
152
153    // binary bitwise operators
154    friend const sc_fix operator & (const sc_fix &, const sc_fix &);
155    friend const sc_fix operator & (const sc_fix &, const sc_fix_fast &);
156    friend const sc_fix operator & (const sc_fix_fast &, const sc_fix &);
157    friend const sc_fix operator | (const sc_fix &, const sc_fix &);
158    friend const sc_fix operator | (const sc_fix &, const sc_fix_fast &);
159    friend const sc_fix operator | (const sc_fix_fast &, const sc_fix &);
160    friend const sc_fix operator ^ (const sc_fix &, const sc_fix &);
161    friend const sc_fix operator ^ (const sc_fix &, const sc_fix_fast &);
162    friend const sc_fix operator ^ (const sc_fix_fast&, const sc_fix &);
163
164    // binary bitwise functions
165    friend void b_and(sc_fix &, const sc_fix &, const sc_fix &);
166    friend void b_and(sc_fix &, const sc_fix &, const sc_fix_fast &);
167    friend void b_and(sc_fix &, const sc_fix_fast &, const sc_fix &);
168    friend void b_or(sc_fix &, const sc_fix &, const sc_fix &);
169    friend void b_or(sc_fix &, const sc_fix &, const sc_fix_fast &);
170    friend void b_or(sc_fix &, const sc_fix_fast &, const sc_fix &);
171    friend void b_xor(sc_fix &, const sc_fix &, const sc_fix &);
172    friend void b_xor(sc_fix &, const sc_fix &, const sc_fix_fast &);
173    friend void b_xor(sc_fix &, const sc_fix_fast &, const sc_fix &);
174
175    // assignment operators
176    sc_fix &operator = (const sc_fix &);
177
178#define DECL_ASN_OP_T(op, tp) sc_fix &operator op (tp);
179
180#define DECL_ASN_OP_OTHER(op) \
181    DECL_ASN_OP_T(op, int64) \
182    DECL_ASN_OP_T(op, uint64) \
183    DECL_ASN_OP_T(op, const sc_int_base &) \
184    DECL_ASN_OP_T(op, const sc_uint_base &) \
185    DECL_ASN_OP_T(op, const sc_signed &) \
186    DECL_ASN_OP_T(op, const sc_unsigned &)
187
188#define DECL_ASN_OP(op) \
189    DECL_ASN_OP_T(op, int) \
190    DECL_ASN_OP_T(op, unsigned int) \
191    DECL_ASN_OP_T(op, long) \
192    DECL_ASN_OP_T(op, unsigned long) \
193    DECL_ASN_OP_T(op, float) \
194    DECL_ASN_OP_T(op, double) \
195    DECL_ASN_OP_T(op, const char *) \
196    DECL_ASN_OP_T(op, const sc_fxval &) \
197    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
198    DECL_ASN_OP_T(op, const sc_fxnum &) \
199    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
200    DECL_ASN_OP_OTHER(op)
201
202    DECL_ASN_OP(=)
203
204    DECL_ASN_OP(*=)
205    DECL_ASN_OP(/=)
206    DECL_ASN_OP(+=)
207    DECL_ASN_OP(-=)
208
209    DECL_ASN_OP_T(<<=, int)
210    DECL_ASN_OP_T(>>=, int)
211
212    DECL_ASN_OP_T(&=, const sc_fix &)
213    DECL_ASN_OP_T(&=, const sc_fix_fast &)
214    DECL_ASN_OP_T(|=, const sc_fix &)
215    DECL_ASN_OP_T(|=, const sc_fix_fast &)
216    DECL_ASN_OP_T(^=, const sc_fix &)
217    DECL_ASN_OP_T(^=, const sc_fix_fast &)
218
219#undef DECL_ASN_OP_T
220#undef DECL_ASN_OP_OTHER
221#undef DECL_ASN_OP
222
223    // auto-increment and auto-decrement
224    const sc_fxval operator ++ (int);
225    const sc_fxval operator -- (int);
226
227    sc_fix& operator ++ ();
228    sc_fix& operator -- ();
229};
230
231
232// ----------------------------------------------------------------------------
233//  CLASS : sc_fix_fast
234//
235//  "Unconstrained" signed fixed-point class; limited precision.
236// ----------------------------------------------------------------------------
237
238class sc_fix_fast : public sc_fxnum_fast
239{
240  public:
241    // constructors
242    explicit sc_fix_fast(sc_fxnum_fast_observer * =0);
243    sc_fix_fast(int, int, sc_fxnum_fast_observer * =0);
244    sc_fix_fast(sc_q_mode, sc_o_mode, sc_fxnum_fast_observer * =0);
245    sc_fix_fast(sc_q_mode, sc_o_mode, int, sc_fxnum_fast_observer * =0);
246    sc_fix_fast(int, int, sc_q_mode, sc_o_mode, sc_fxnum_fast_observer * =0);
247    sc_fix_fast(int, int, sc_q_mode, sc_o_mode, int,
248                sc_fxnum_fast_observer * =0);
249    explicit sc_fix_fast(const sc_fxcast_switch &,
250                         sc_fxnum_fast_observer * =0);
251    sc_fix_fast(int, int, const sc_fxcast_switch &,
252                sc_fxnum_fast_observer * =0);
253    sc_fix_fast(sc_q_mode, sc_o_mode, const sc_fxcast_switch &,
254                sc_fxnum_fast_observer * =0);
255    sc_fix_fast(sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &,
256                sc_fxnum_fast_observer * =0);
257    sc_fix_fast(int, int, sc_q_mode, sc_o_mode, const sc_fxcast_switch &,
258                sc_fxnum_fast_observer * =0);
259    sc_fix_fast(int, int, sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &,
260                sc_fxnum_fast_observer * =0);
261    explicit sc_fix_fast(const sc_fxtype_params &,
262                         sc_fxnum_fast_observer * =0);
263    sc_fix_fast(const sc_fxtype_params &, const sc_fxcast_switch &,
264                sc_fxnum_fast_observer * =0);
265
266#define DECL_CTORS_T(tp) \
267    sc_fix_fast(tp, int, int, sc_fxnum_fast_observer * = 0); \
268    sc_fix_fast(tp, sc_q_mode, sc_o_mode, sc_fxnum_fast_observer * = 0); \
269    sc_fix_fast(tp, sc_q_mode, sc_o_mode, int, sc_fxnum_fast_observer * = 0); \
270    sc_fix_fast(tp, int, int, sc_q_mode, sc_o_mode, \
271                sc_fxnum_fast_observer * = 0); \
272    sc_fix_fast(tp, int, int, sc_q_mode, sc_o_mode, int, \
273                sc_fxnum_fast_observer * = 0); \
274    sc_fix_fast(tp, const sc_fxcast_switch &, sc_fxnum_fast_observer * = 0); \
275    sc_fix_fast(tp, int, int, const sc_fxcast_switch &, \
276                sc_fxnum_fast_observer * = 0); \
277    sc_fix_fast(tp, sc_q_mode, sc_o_mode, const sc_fxcast_switch &, \
278                sc_fxnum_fast_observer * = 0); \
279    sc_fix_fast(tp, sc_q_mode, sc_o_mode, int, const sc_fxcast_switch &, \
280                sc_fxnum_fast_observer * = 0); \
281    sc_fix_fast(tp, int, int, sc_q_mode, sc_o_mode, const sc_fxcast_switch &, \
282                sc_fxnum_fast_observer * = 0); \
283    sc_fix_fast(tp, int, int, sc_q_mode, sc_o_mode, int, \
284                const sc_fxcast_switch &, sc_fxnum_fast_observer * = 0); \
285    sc_fix_fast(tp, const sc_fxtype_params &, sc_fxnum_fast_observer * = 0); \
286    sc_fix_fast(tp, const sc_fxtype_params &, const sc_fxcast_switch &, \
287                sc_fxnum_fast_observer * = 0);
288
289#define DECL_CTORS_T_A(tp) \
290    sc_fix_fast(tp, sc_fxnum_fast_observer * =0); \
291    DECL_CTORS_T(tp)
292
293#define DECL_CTORS_T_B(tp) \
294    explicit sc_fix_fast(tp, sc_fxnum_fast_observer * =0); \
295    DECL_CTORS_T(tp)
296
297    DECL_CTORS_T_A(int)
298    DECL_CTORS_T_A(unsigned int)
299    DECL_CTORS_T_A(long)
300    DECL_CTORS_T_A(unsigned long)
301    DECL_CTORS_T_A(float)
302    DECL_CTORS_T_A(double)
303    DECL_CTORS_T_A(const char *)
304    DECL_CTORS_T_A(const sc_fxval &)
305    DECL_CTORS_T_A(const sc_fxval_fast &)
306    DECL_CTORS_T_A(const sc_fxnum &)
307    DECL_CTORS_T_A(const sc_fxnum_fast &)
308
309    DECL_CTORS_T_B(int64)
310    DECL_CTORS_T_B(uint64)
311    DECL_CTORS_T_B(const sc_int_base &)
312    DECL_CTORS_T_B(const sc_uint_base &)
313    DECL_CTORS_T_B(const sc_signed &)
314    DECL_CTORS_T_B(const sc_unsigned &)
315
316#undef DECL_CTORS_T
317#undef DECL_CTORS_T_A
318#undef DECL_CTORS_T_B
319
320    // copy constructor
321    sc_fix_fast(const sc_fix_fast &);
322
323    // unary bitwise operators
324    const sc_fix_fast operator ~ () const;
325
326    // unary bitwise functions
327    friend void b_not(sc_fix_fast &, const sc_fix_fast &);
328
329    // binary bitwise operators
330    friend const sc_fix_fast operator & (
331            const sc_fix_fast &, const sc_fix_fast &);
332    friend const sc_fix_fast operator ^ (
333            const sc_fix_fast &, const sc_fix_fast &);
334    friend const sc_fix_fast operator | (
335            const sc_fix_fast &, const sc_fix_fast &);
336
337    // binary bitwise functions
338    friend void b_and(sc_fix_fast &, const sc_fix_fast &, const sc_fix_fast &);
339    friend void b_or(sc_fix_fast &, const sc_fix_fast &, const sc_fix_fast &);
340    friend void b_xor(sc_fix_fast &, const sc_fix_fast &, const sc_fix_fast &);
341
342    // assignment operators
343    sc_fix_fast &operator = (const sc_fix_fast &);
344
345#define DECL_ASN_OP_T(op,tp) sc_fix_fast &operator op (tp);
346
347#define DECL_ASN_OP_OTHER(op) \
348    DECL_ASN_OP_T(op, int64) \
349    DECL_ASN_OP_T(op, uint64) \
350    DECL_ASN_OP_T(op, const sc_int_base &) \
351    DECL_ASN_OP_T(op, const sc_uint_base &) \
352    DECL_ASN_OP_T(op, const sc_signed &) \
353    DECL_ASN_OP_T(op, const sc_unsigned &)
354
355#define DECL_ASN_OP(op) \
356    DECL_ASN_OP_T(op, int) \
357    DECL_ASN_OP_T(op, unsigned int) \
358    DECL_ASN_OP_T(op, long) \
359    DECL_ASN_OP_T(op, unsigned long) \
360    DECL_ASN_OP_T(op, float) \
361    DECL_ASN_OP_T(op, double) \
362    DECL_ASN_OP_T(op, const char *) \
363    DECL_ASN_OP_T(op, const sc_fxval &) \
364    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
365    DECL_ASN_OP_T(op, const sc_fxnum &) \
366    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
367    DECL_ASN_OP_OTHER(op)
368
369    DECL_ASN_OP(=)
370
371    DECL_ASN_OP(*=)
372    DECL_ASN_OP(/=)
373    DECL_ASN_OP(+=)
374    DECL_ASN_OP(-=)
375
376    DECL_ASN_OP_T(<<=, int)
377    DECL_ASN_OP_T(>>=, int)
378
379    DECL_ASN_OP_T(&=, const sc_fix &)
380    DECL_ASN_OP_T(&=, const sc_fix_fast &)
381    DECL_ASN_OP_T(|=, const sc_fix &)
382    DECL_ASN_OP_T(|=, const sc_fix_fast &)
383    DECL_ASN_OP_T(^=, const sc_fix &)
384    DECL_ASN_OP_T(^=, const sc_fix_fast &)
385
386#undef DECL_ASN_OP_T
387#undef DECL_ASN_OP_OTHER
388#undef DECL_ASN_OP
389
390    // auto-increment and auto-decrement
391    const sc_fxval_fast operator ++ (int);
392    const sc_fxval_fast operator -- (int);
393
394    sc_fix_fast& operator ++ ();
395    sc_fix_fast& operator -- ();
396};
397
398
399// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
400
401// ----------------------------------------------------------------------------
402//  CLASS : sc_fix
403//
404//  "Unconstrained" signed fixed-point class; arbitrary precision.
405// ----------------------------------------------------------------------------
406
407// constructors
408inline sc_fix::sc_fix(sc_fxnum_observer *observer_) :
409        sc_fxnum(sc_fxtype_params(), SC_TC_, sc_fxcast_switch(), observer_)
410{}
411
412inline sc_fix::sc_fix(int wl_, int iwl_, sc_fxnum_observer *observer_) :
413        sc_fxnum(sc_fxtype_params(wl_, iwl_), SC_TC_, sc_fxcast_switch(),
414                 observer_)
415{}
416
417inline sc_fix::sc_fix(sc_q_mode qm, sc_o_mode om,
418                      sc_fxnum_observer *observer_) :
419        sc_fxnum(sc_fxtype_params(qm, om), SC_TC_, sc_fxcast_switch(),
420                 observer_ )
421{}
422
423inline sc_fix::sc_fix(sc_q_mode qm, sc_o_mode om, int nb,
424                      sc_fxnum_observer *observer_) :
425        sc_fxnum(sc_fxtype_params(qm, om, nb), SC_TC_, sc_fxcast_switch(),
426                 observer_)
427{}
428
429inline sc_fix::sc_fix(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
430                      sc_fxnum_observer *observer_) :
431        sc_fxnum(sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_,
432                 sc_fxcast_switch(), observer_)
433{}
434
435inline sc_fix::sc_fix(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
436                      sc_fxnum_observer* observer_) :
437        sc_fxnum(sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_,
438                 sc_fxcast_switch(), observer_)
439{}
440
441inline sc_fix::sc_fix(const sc_fxcast_switch &cast_sw,
442                      sc_fxnum_observer *observer_) :
443        sc_fxnum(sc_fxtype_params(), SC_TC_, cast_sw, observer_)
444{}
445
446inline sc_fix::sc_fix(int wl_, int iwl_, const sc_fxcast_switch &cast_sw,
447                      sc_fxnum_observer *observer_) :
448        sc_fxnum(sc_fxtype_params(wl_, iwl_), SC_TC_, cast_sw, observer_)
449{}
450
451inline sc_fix::sc_fix(sc_q_mode qm, sc_o_mode om,
452                      const sc_fxcast_switch &cast_sw,
453                      sc_fxnum_observer *observer_) :
454        sc_fxnum(sc_fxtype_params(qm, om), SC_TC_, cast_sw, observer_)
455{}
456
457inline sc_fix::sc_fix(sc_q_mode qm, sc_o_mode om, int nb,
458                      const sc_fxcast_switch &cast_sw,
459                      sc_fxnum_observer *observer_) :
460        sc_fxnum(sc_fxtype_params(qm, om, nb), SC_TC_, cast_sw, observer_)
461{}
462
463inline sc_fix::sc_fix(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
464                      const sc_fxcast_switch &cast_sw,
465                      sc_fxnum_observer *observer_) :
466        sc_fxnum(sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, cast_sw,
467                                  observer_)
468{}
469
470inline sc_fix::sc_fix(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
471                      const sc_fxcast_switch &cast_sw,
472                      sc_fxnum_observer *observer_) :
473        sc_fxnum(sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, cast_sw,
474                 observer_)
475{}
476
477inline sc_fix::sc_fix(const sc_fxtype_params &type_params_,
478                      sc_fxnum_observer *observer_) :
479        sc_fxnum( type_params_, SC_TC_, sc_fxcast_switch(), observer_)
480{}
481
482inline sc_fix::sc_fix(const sc_fxtype_params &type_params_,
483                      const sc_fxcast_switch &cast_sw,
484                      sc_fxnum_observer *observer_) :
485        sc_fxnum(type_params_, SC_TC_, cast_sw, observer_)
486{}
487
488#define DEFN_CTORS_T_A(tp) \
489inline sc_fix::sc_fix(tp a, sc_fxnum_observer *observer_) : \
490        sc_fxnum(a, sc_fxtype_params(), SC_TC_, sc_fxcast_switch(), \
491                 observer_) \
492{} \
493 \
494inline sc_fix::sc_fix(tp a, int wl_, int iwl_, \
495                      sc_fxnum_observer *observer_) : \
496        sc_fxnum(a, sc_fxtype_params(wl_, iwl_), SC_TC_, sc_fxcast_switch(), \
497                 observer_) \
498{} \
499 \
500inline sc_fix::sc_fix(tp a,  sc_q_mode qm, sc_o_mode om, \
501                      sc_fxnum_observer *observer_) : \
502        sc_fxnum(a, sc_fxtype_params(qm, om), SC_TC_, sc_fxcast_switch(), \
503                 observer_) \
504{} \
505 \
506inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
507                      sc_fxnum_observer *observer_) : \
508        sc_fxnum(a, sc_fxtype_params(qm, om, nb), SC_TC_, \
509                 sc_fxcast_switch(), observer_) \
510{} \
511 \
512inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
513                      sc_fxnum_observer *observer_) : \
514        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
515                 sc_fxcast_switch(), observer_) \
516{} \
517 \
518inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
519                      int nb, sc_fxnum_observer *observer_) : \
520        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
521                 sc_fxcast_switch(), observer_) \
522{} \
523 \
524inline sc_fix::sc_fix(tp a, const sc_fxcast_switch &cast_sw, \
525                      sc_fxnum_observer *observer_) : \
526        sc_fxnum(a, sc_fxtype_params(), SC_TC_, cast_sw, observer_) \
527{} \
528 \
529inline sc_fix::sc_fix(tp a, int wl_, int iwl_, \
530                      const sc_fxcast_switch &cast_sw, \
531                      sc_fxnum_observer *observer_) : \
532        sc_fxnum(a, sc_fxtype_params(wl_, iwl_), SC_TC_, cast_sw, observer_) \
533{} \
534 \
535inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, \
536                      const sc_fxcast_switch &cast_sw, \
537                      sc_fxnum_observer *observer_) : \
538        sc_fxnum(a, sc_fxtype_params(qm, om), SC_TC_, cast_sw, observer_) \
539{} \
540 \
541inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
542                      const sc_fxcast_switch &cast_sw, \
543                      sc_fxnum_observer *observer_) : \
544        sc_fxnum(a, sc_fxtype_params(qm, om, nb), SC_TC_, cast_sw, observer_) \
545{} \
546 \
547inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
548                      const sc_fxcast_switch &cast_sw, \
549                      sc_fxnum_observer *observer_) : \
550        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, cast_sw, \
551                 observer_) \
552{} \
553 \
554inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
555                      int nb, const sc_fxcast_switch &cast_sw, \
556                      sc_fxnum_observer *observer_) : \
557        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, cast_sw, \
558                 observer_) \
559{} \
560 \
561inline sc_fix::sc_fix(tp a, const sc_fxtype_params &type_params_, \
562                      sc_fxnum_observer *observer_) : \
563        sc_fxnum(a, type_params_, SC_TC_, sc_fxcast_switch(), observer_) \
564{} \
565 \
566inline sc_fix::sc_fix(tp a, const sc_fxtype_params &type_params_, \
567                      const sc_fxcast_switch &cast_sw, \
568                      sc_fxnum_observer *observer_) : \
569        sc_fxnum(a, type_params_, SC_TC_, cast_sw, observer_) \
570{}
571
572#define DEFN_CTORS_T_B(tp) \
573inline sc_fix::sc_fix(tp a, sc_fxnum_observer *observer_) : \
574        sc_fxnum(a, a.type_params(), SC_TC_, sc_fxcast_switch(), observer_) \
575{} \
576 \
577inline sc_fix::sc_fix(tp a, int wl_, int iwl_, \
578                      sc_fxnum_observer *observer_) : \
579        sc_fxnum(a, sc_fxtype_params(a.type_params(), wl_, iwl_), SC_TC_, \
580                 sc_fxcast_switch(), observer_) \
581{} \
582 \
583inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, \
584                      sc_fxnum_observer *observer_) : \
585        sc_fxnum(a, sc_fxtype_params(a.type_params(), qm, om), SC_TC_, \
586                 sc_fxcast_switch(), observer_) \
587{} \
588 \
589inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
590                      sc_fxnum_observer *observer_) : \
591        sc_fxnum(a, sc_fxtype_params(a.type_params(), qm, om, nb), SC_TC_, \
592                 sc_fxcast_switch(), observer_) \
593{} \
594 \
595inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
596                      sc_fxnum_observer *observer_) : \
597        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
598                 sc_fxcast_switch(), observer_) \
599{} \
600 \
601inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
602                      int nb, sc_fxnum_observer *observer_) : \
603        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
604                 sc_fxcast_switch(), observer_) \
605{} \
606 \
607inline sc_fix::sc_fix(tp a, const sc_fxcast_switch &cast_sw, \
608                      sc_fxnum_observer *observer_) : \
609        sc_fxnum(a, a.type_params(), SC_TC_, cast_sw, observer_) \
610{} \
611 \
612inline sc_fix::sc_fix(tp a, int wl_, int iwl_, \
613                      const sc_fxcast_switch &cast_sw, \
614                      sc_fxnum_observer *observer_) : \
615        sc_fxnum(a, sc_fxtype_params(a.type_params(), wl_, iwl_), SC_TC_, \
616                 cast_sw, observer_) \
617{} \
618 \
619inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, \
620                      const sc_fxcast_switch &cast_sw, \
621                      sc_fxnum_observer *observer_) : \
622        sc_fxnum(a, sc_fxtype_params(a.type_params(), qm, om), SC_TC_, \
623                 cast_sw, observer_) \
624{} \
625 \
626inline sc_fix::sc_fix(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
627                      const sc_fxcast_switch &cast_sw, \
628                      sc_fxnum_observer *observer_) : \
629        sc_fxnum(a, sc_fxtype_params(a.type_params(), qm, om, nb), SC_TC_, \
630                 cast_sw, observer_) \
631{} \
632 \
633inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
634                      const sc_fxcast_switch &cast_sw, \
635                      sc_fxnum_observer *observer_) : \
636        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, cast_sw, \
637                 observer_) \
638{} \
639 \
640inline sc_fix::sc_fix(tp a, int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
641                      int nb, const sc_fxcast_switch &cast_sw, \
642                      sc_fxnum_observer *observer_) : \
643        sc_fxnum(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, cast_sw, \
644                 observer_) \
645{} \
646 \
647inline sc_fix::sc_fix(tp a, const sc_fxtype_params &type_params_, \
648                      sc_fxnum_observer *observer_) : \
649        sc_fxnum(a, type_params_, SC_TC_, sc_fxcast_switch(), observer_) \
650{} \
651 \
652inline sc_fix::sc_fix(tp a, const sc_fxtype_params &type_params_, \
653                      const sc_fxcast_switch &cast_sw, \
654                      sc_fxnum_observer *observer_) : \
655        sc_fxnum(a, type_params_, SC_TC_, cast_sw, observer_) \
656{}
657
658DEFN_CTORS_T_A(int)
659DEFN_CTORS_T_A(unsigned int)
660DEFN_CTORS_T_A(long)
661DEFN_CTORS_T_A(unsigned long)
662DEFN_CTORS_T_A(float)
663DEFN_CTORS_T_A(double)
664DEFN_CTORS_T_A(const char *)
665DEFN_CTORS_T_A(const sc_fxval &)
666DEFN_CTORS_T_A(const sc_fxval_fast &)
667DEFN_CTORS_T_B(const sc_fxnum &)
668DEFN_CTORS_T_B(const sc_fxnum_fast &)
669
670DEFN_CTORS_T_A(int64)
671DEFN_CTORS_T_A(uint64)
672DEFN_CTORS_T_A(const sc_int_base &)
673DEFN_CTORS_T_A(const sc_uint_base &)
674DEFN_CTORS_T_A(const sc_signed &)
675DEFN_CTORS_T_A(const sc_unsigned &)
676
677#undef DEFN_CTORS_T_A
678#undef DEFN_CTORS_T_B
679
680// copy constructor
681inline sc_fix::sc_fix(const sc_fix &a) :
682        sc_fxnum(a, a.type_params(), SC_TC_, sc_fxcast_switch(), 0)
683{}
684
685// unary bitwise operators
686inline const sc_fix sc_fix::operator ~ () const
687{
688    SC_FXNUM_OBSERVER_READ_(*this)
689    int iwl_c = iwl();
690    int wl_c = wl();
691    sc_fix c(wl_c, iwl_c);
692    for (int i = iwl_c - wl_c; i < iwl_c; ++i)
693        c.set_bit(i, !get_bit(i));
694    return sc_fix(c, wl_c, iwl_c);
695}
696
697// unary bitwise functions
698inline void
699b_not(sc_fix &c, const sc_fix &a)
700{
701    SC_FXNUM_OBSERVER_READ_(a)
702    int iwl_c = c.iwl();
703    for (int i = iwl_c - c.wl(); i < iwl_c; ++i)
704        c.set_bit(i, !a.get_bit(i));
705    c.cast();
706    SC_FXNUM_OBSERVER_WRITE_(c)
707}
708
709// binary bitwise operators
710#define DEFN_BIN_OP_T(op, op2, tp1, tp2) \
711inline const sc_fix \
712operator op (const tp1 &a, const tp2 &b) \
713{ \
714    a.observer_read(); \
715    b.observer_read(); \
716    int iwl_a = a.iwl(); \
717    int iwl_b = b.iwl(); \
718    int iwl_c = sc_max(iwl_a, iwl_b); \
719    int fwl_c = sc_max(a.wl() - iwl_a, b.wl() - iwl_b); \
720    sc_fix c(iwl_c + fwl_c, iwl_c); \
721    for (int i = -fwl_c; i < iwl_c; ++ i) \
722        c.set_bit(i, a.get_bit(i) op2 b.get_bit(i)); \
723    return sc_fix(c, iwl_c + fwl_c, iwl_c); \
724}
725
726DEFN_BIN_OP_T(&, &&, sc_fix, sc_fix)
727DEFN_BIN_OP_T(&, &&, sc_fix, sc_fix_fast)
728DEFN_BIN_OP_T(&, &&, sc_fix_fast, sc_fix)
729
730DEFN_BIN_OP_T(|, ||, sc_fix, sc_fix)
731DEFN_BIN_OP_T(|, ||, sc_fix, sc_fix_fast)
732DEFN_BIN_OP_T(|, ||, sc_fix_fast, sc_fix)
733
734DEFN_BIN_OP_T(^, !=, sc_fix, sc_fix)
735DEFN_BIN_OP_T(^, !=, sc_fix, sc_fix_fast)
736DEFN_BIN_OP_T(^, !=, sc_fix_fast, sc_fix)
737
738#undef DEFN_BIN_OP_T
739
740// binary bitwise functions
741#define DEFN_BIN_FNC_T(fnc, op2, tp1, tp2) \
742inline void \
743fnc (sc_fix &c, const tp1 &a, const tp2 &b) \
744{ \
745    a.observer_read(); \
746    b.observer_read(); \
747    int iwl_c = c.iwl(); \
748    for (int i = iwl_c - c.wl(); i < iwl_c; ++i) \
749        c.set_bit(i, a.get_bit(i) op2 b.get_bit(i)); \
750    c.cast(); \
751    SC_FXNUM_OBSERVER_WRITE_(c) \
752}
753
754DEFN_BIN_FNC_T(b_and, &&, sc_fix, sc_fix)
755DEFN_BIN_FNC_T(b_and, &&, sc_fix, sc_fix_fast)
756DEFN_BIN_FNC_T(b_and, &&, sc_fix_fast, sc_fix)
757
758DEFN_BIN_FNC_T(b_or, ||, sc_fix, sc_fix)
759DEFN_BIN_FNC_T(b_or, ||, sc_fix, sc_fix_fast)
760DEFN_BIN_FNC_T(b_or, ||, sc_fix_fast, sc_fix)
761
762DEFN_BIN_FNC_T(b_xor, !=, sc_fix, sc_fix)
763DEFN_BIN_FNC_T(b_xor, !=, sc_fix, sc_fix_fast)
764DEFN_BIN_FNC_T(b_xor, !=, sc_fix_fast, sc_fix)
765
766#undef DEFN_BIN_FNC_T
767
768// assignment operators
769inline
770sc_fix &
771sc_fix::operator = (const sc_fix &a)
772{
773    sc_fxnum::operator = (a);
774    return *this;
775}
776
777#define DEFN_ASN_OP_T(op, tp) \
778inline sc_fix & \
779sc_fix::operator op (tp a) \
780{ \
781    sc_fxnum::operator op(a); \
782    return *this; \
783}
784
785#define DEFN_ASN_OP_OTHER(op) \
786DEFN_ASN_OP_T(op, int64) \
787DEFN_ASN_OP_T(op, uint64) \
788DEFN_ASN_OP_T(op, const sc_int_base &) \
789DEFN_ASN_OP_T(op, const sc_uint_base &) \
790DEFN_ASN_OP_T(op, const sc_signed &) \
791DEFN_ASN_OP_T(op, const sc_unsigned &)
792
793#define DEFN_ASN_OP(op) \
794DEFN_ASN_OP_T(op, int) \
795DEFN_ASN_OP_T(op, unsigned int) \
796DEFN_ASN_OP_T(op, long) \
797DEFN_ASN_OP_T(op, unsigned long) \
798DEFN_ASN_OP_T(op, float) \
799DEFN_ASN_OP_T(op, double) \
800DEFN_ASN_OP_T(op, const char *) \
801DEFN_ASN_OP_T(op, const sc_fxval &) \
802DEFN_ASN_OP_T(op, const sc_fxval_fast &) \
803DEFN_ASN_OP_T(op, const sc_fxnum &) \
804DEFN_ASN_OP_T(op, const sc_fxnum_fast &) \
805DEFN_ASN_OP_OTHER(op)
806
807DEFN_ASN_OP(=)
808
809DEFN_ASN_OP(*=)
810DEFN_ASN_OP(/=)
811DEFN_ASN_OP(+=)
812DEFN_ASN_OP(-=)
813
814DEFN_ASN_OP_T(<<=, int)
815DEFN_ASN_OP_T(>>=, int)
816
817#undef DEFN_ASN_OP_T
818#undef DEFN_ASN_OP_OTHER
819#undef DEFN_ASN_OP
820
821#define DEFN_ASN_OP_T(op, op2, tp) \
822inline sc_fix & \
823sc_fix::operator op (const tp &b) \
824{ \
825    SC_FXNUM_OBSERVER_READ_(*this) \
826    b.observer_read(); \
827    int iwl_c = iwl(); \
828    for (int i = iwl_c - wl(); i < iwl_c; ++i) \
829        set_bit(i, get_bit(i) op2 b.get_bit(i)); \
830    cast(); \
831    SC_FXNUM_OBSERVER_WRITE_(*this) \
832    return *this; \
833}
834
835DEFN_ASN_OP_T(&=, &&, sc_fix)
836DEFN_ASN_OP_T(&=, &&, sc_fix_fast)
837DEFN_ASN_OP_T(|=, ||, sc_fix)
838DEFN_ASN_OP_T(|=, ||, sc_fix_fast)
839DEFN_ASN_OP_T(^=, !=, sc_fix)
840DEFN_ASN_OP_T(^=, !=, sc_fix_fast)
841
842#undef DEFN_ASN_OP_T
843
844// auto-increment and auto-decrement
845inline const sc_fxval
846sc_fix::operator ++ (int)
847{
848    return sc_fxval(sc_fxnum::operator ++ (0));
849}
850
851inline const sc_fxval
852sc_fix::operator -- (int)
853{
854    return sc_fxval(sc_fxnum::operator -- (0));
855}
856
857inline sc_fix &
858sc_fix::operator ++ ()
859{
860    sc_fxnum::operator ++ ();
861    return *this;
862}
863
864inline sc_fix &
865sc_fix::operator -- ()
866{
867    sc_fxnum::operator -- ();
868    return *this;
869}
870
871
872// ----------------------------------------------------------------------------
873// CLASS : sc_fix_fast
874//
875// "Unconstrained" signed fixed-point class; limited precision.
876// ----------------------------------------------------------------------------
877
878// constructors
879inline sc_fix_fast::sc_fix_fast(sc_fxnum_fast_observer *observer_) :
880        sc_fxnum_fast(sc_fxtype_params(), SC_TC_, sc_fxcast_switch(),
881                      observer_)
882{}
883
884inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_,
885                                sc_fxnum_fast_observer *observer_) :
886        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_), SC_TC_, sc_fxcast_switch(),
887                      observer_ )
888{}
889
890inline sc_fix_fast::sc_fix_fast(sc_q_mode qm, sc_o_mode om,
891                                sc_fxnum_fast_observer *observer_) :
892        sc_fxnum_fast(sc_fxtype_params(qm, om), SC_TC_, sc_fxcast_switch(),
893                      observer_ )
894{}
895
896inline sc_fix_fast::sc_fix_fast(sc_q_mode qm, sc_o_mode om, int nb,
897                                sc_fxnum_fast_observer *observer_) :
898        sc_fxnum_fast(sc_fxtype_params(qm, om, nb), SC_TC_, sc_fxcast_switch(),
899                      observer_ )
900{}
901
902inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
903                                sc_fxnum_fast_observer *observer_) :
904        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_,
905                      sc_fxcast_switch(), observer_)
906{}
907
908inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
909                                int nb, sc_fxnum_fast_observer *observer_) :
910        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_,
911                      sc_fxcast_switch(), observer_)
912{}
913
914inline sc_fix_fast::sc_fix_fast(const sc_fxcast_switch &cast_sw,
915                                sc_fxnum_fast_observer *observer_) :
916        sc_fxnum_fast(sc_fxtype_params(), SC_TC_, cast_sw, observer_)
917{}
918
919inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_,
920                                const sc_fxcast_switch &cast_sw,
921                                sc_fxnum_fast_observer *observer_) :
922        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_), SC_TC_, cast_sw, observer_)
923{}
924
925inline sc_fix_fast::sc_fix_fast(sc_q_mode qm, sc_o_mode om,
926                                const sc_fxcast_switch &cast_sw,
927                                sc_fxnum_fast_observer *observer_) :
928        sc_fxnum_fast(sc_fxtype_params(qm, om), SC_TC_, cast_sw, observer_)
929{}
930
931inline sc_fix_fast::sc_fix_fast(sc_q_mode qm, sc_o_mode om, int nb,
932                                const sc_fxcast_switch &cast_sw,
933                                sc_fxnum_fast_observer *observer_) :
934        sc_fxnum_fast(sc_fxtype_params(qm, om, nb), SC_TC_, cast_sw, observer_)
935{}
936
937inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
938                                const sc_fxcast_switch &cast_sw,
939                                sc_fxnum_fast_observer *observer_) :
940        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, cast_sw,
941                      observer_)
942{}
943
944inline sc_fix_fast::sc_fix_fast(int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
945                                int nb, const sc_fxcast_switch &cast_sw,
946                                sc_fxnum_fast_observer *observer_) :
947        sc_fxnum_fast(sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, cast_sw,
948                      observer_)
949{}
950
951inline sc_fix_fast::sc_fix_fast(const sc_fxtype_params &type_params_,
952                                sc_fxnum_fast_observer *observer_) :
953        sc_fxnum_fast(type_params_, SC_TC_, sc_fxcast_switch(), observer_)
954{}
955
956inline sc_fix_fast::sc_fix_fast(const sc_fxtype_params &type_params_,
957                                const sc_fxcast_switch &cast_sw,
958                                sc_fxnum_fast_observer *observer_) :
959        sc_fxnum_fast(type_params_, SC_TC_, cast_sw, observer_)
960{}
961
962#define DEFN_CTORS_T_A(tp) \
963inline sc_fix_fast::sc_fix_fast(tp a, sc_fxnum_fast_observer *observer_ ) : \
964        sc_fxnum_fast(a, sc_fxtype_params(), SC_TC_, sc_fxcast_switch(), \
965                      observer_ ) \
966{} \
967 \
968inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, \
969                                sc_fxnum_fast_observer *observer_) : \
970        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_), SC_TC_, \
971                      sc_fxcast_switch(), observer_) \
972{} \
973 \
974inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, \
975                                sc_fxnum_fast_observer *observer_) : \
976        sc_fxnum_fast(a, sc_fxtype_params(qm, om), SC_TC_, \
977                      sc_fxcast_switch(), observer_) \
978{} \
979 \
980inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
981                                sc_fxnum_fast_observer *observer_ ) : \
982        sc_fxnum_fast(a, sc_fxtype_params(qm, om, nb), SC_TC_, \
983                      sc_fxcast_switch(), observer_) \
984{} \
985 \
986inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
987                                sc_o_mode om, \
988                                sc_fxnum_fast_observer *observer_) : \
989        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
990                      sc_fxcast_switch(), observer_) \
991{} \
992 \
993inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
994                                sc_o_mode om, int nb, \
995                                sc_fxnum_fast_observer *observer_) : \
996        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
997                      sc_fxcast_switch(), observer_) \
998{} \
999 \
1000inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxcast_switch &cast_sw, \
1001                                sc_fxnum_fast_observer *observer_) : \
1002        sc_fxnum_fast(a, sc_fxtype_params(), SC_TC_, cast_sw, observer_) \
1003{} \
1004 \
1005inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, \
1006                                const sc_fxcast_switch &cast_sw, \
1007                                sc_fxnum_fast_observer *observer_) : \
1008        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_), SC_TC_, cast_sw, \
1009                      observer_ ) \
1010{} \
1011 \
1012inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, \
1013                                const sc_fxcast_switch &cast_sw, \
1014                                sc_fxnum_fast_observer *observer_) : \
1015        sc_fxnum_fast(a, sc_fxtype_params(qm, om), SC_TC_, cast_sw, \
1016                      observer_) \
1017{} \
1018 \
1019inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
1020                                const sc_fxcast_switch &cast_sw, \
1021                                sc_fxnum_fast_observer *observer_) : \
1022        sc_fxnum_fast(a, sc_fxtype_params(qm, om, nb), SC_TC_, cast_sw, \
1023                      observer_ ) \
1024{} \
1025 \
1026inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1027                                sc_o_mode om, \
1028                                const sc_fxcast_switch &cast_sw, \
1029                                sc_fxnum_fast_observer *observer_) : \
1030        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
1031                      cast_sw, observer_) \
1032{} \
1033 \
1034inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1035                                sc_o_mode om, int nb, \
1036                                const sc_fxcast_switch &cast_sw, \
1037                                sc_fxnum_fast_observer *observer_) : \
1038        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
1039                      cast_sw, observer_) \
1040{} \
1041 \
1042inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxtype_params &type_params_, \
1043                                sc_fxnum_fast_observer *observer_) : \
1044        sc_fxnum_fast(a, type_params_, SC_TC_, sc_fxcast_switch(), observer_) \
1045{} \
1046 \
1047inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxtype_params &type_params_, \
1048                                const sc_fxcast_switch &cast_sw, \
1049                                sc_fxnum_fast_observer *observer_) : \
1050        sc_fxnum_fast(a, type_params_, SC_TC_, cast_sw, observer_) \
1051{}
1052
1053#define DEFN_CTORS_T_B(tp) \
1054inline sc_fix_fast::sc_fix_fast(tp a, sc_fxnum_fast_observer *observer_) : \
1055        sc_fxnum_fast(a, a.type_params(), SC_TC_, sc_fxcast_switch(), \
1056                      observer_ ) \
1057{} \
1058 \
1059inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, \
1060                                sc_fxnum_fast_observer *observer_) : \
1061        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), wl_, iwl_), \
1062                      SC_TC_, sc_fxcast_switch(), observer_) \
1063{} \
1064 \
1065inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, \
1066                                sc_fxnum_fast_observer *observer_) : \
1067        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), qm, om), SC_TC_, \
1068                      sc_fxcast_switch(), observer_) \
1069{} \
1070 \
1071inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
1072                                sc_fxnum_fast_observer *observer_) : \
1073        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), qm, om, nb), \
1074                      SC_TC_, sc_fxcast_switch(), observer_) \
1075{} \
1076 \
1077inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1078                                sc_o_mode om, \
1079                                sc_fxnum_fast_observer *observer_) : \
1080        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
1081                      sc_fxcast_switch(), observer_) \
1082{} \
1083 \
1084inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1085                                sc_o_mode om, int nb, \
1086                                sc_fxnum_fast_observer *observer_) : \
1087        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
1088                      sc_fxcast_switch(), observer_) \
1089{} \
1090 \
1091inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxcast_switch &cast_sw, \
1092                                sc_fxnum_fast_observer *observer_) : \
1093        sc_fxnum_fast(a, a.type_params(), SC_TC_, cast_sw, observer_) \
1094{} \
1095 \
1096inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, \
1097                                const sc_fxcast_switch &cast_sw, \
1098                                sc_fxnum_fast_observer *observer_) : \
1099        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), wl_, iwl_), \
1100                      SC_TC_, cast_sw, observer_) \
1101{} \
1102 \
1103inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, \
1104                                const sc_fxcast_switch &cast_sw, \
1105                                sc_fxnum_fast_observer *observer_) : \
1106        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), qm, om), SC_TC_, \
1107                      cast_sw, observer_) \
1108{} \
1109 \
1110inline sc_fix_fast::sc_fix_fast(tp a, sc_q_mode qm, sc_o_mode om, int nb, \
1111                                const sc_fxcast_switch &cast_sw, \
1112                                sc_fxnum_fast_observer *observer_) : \
1113        sc_fxnum_fast(a, sc_fxtype_params(a.type_params(), qm, om, nb), \
1114                      SC_TC_, cast_sw, observer_) \
1115{} \
1116 \
1117inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1118                                sc_o_mode om, \
1119                                const sc_fxcast_switch &cast_sw, \
1120                                sc_fxnum_fast_observer *observer_) : \
1121        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om), SC_TC_, \
1122                      cast_sw, observer_) \
1123{} \
1124 \
1125inline sc_fix_fast::sc_fix_fast(tp a, int wl_, int iwl_, sc_q_mode qm, \
1126                                sc_o_mode om, int nb, \
1127                                const sc_fxcast_switch &cast_sw, \
1128                                sc_fxnum_fast_observer *observer_) : \
1129        sc_fxnum_fast(a, sc_fxtype_params(wl_, iwl_, qm, om, nb), SC_TC_, \
1130                      cast_sw, observer_) \
1131{} \
1132 \
1133inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxtype_params &type_params_, \
1134                                sc_fxnum_fast_observer *observer_) : \
1135        sc_fxnum_fast(a, type_params_, SC_TC_, sc_fxcast_switch(), observer_) \
1136{} \
1137 \
1138inline sc_fix_fast::sc_fix_fast(tp a, const sc_fxtype_params &type_params_, \
1139                                const sc_fxcast_switch &cast_sw, \
1140                                sc_fxnum_fast_observer *observer_) : \
1141        sc_fxnum_fast(a, type_params_, SC_TC_, cast_sw, observer_ ) \
1142{}
1143
1144DEFN_CTORS_T_A(int)
1145DEFN_CTORS_T_A(unsigned int)
1146DEFN_CTORS_T_A(long)
1147DEFN_CTORS_T_A(unsigned long)
1148DEFN_CTORS_T_A(float)
1149DEFN_CTORS_T_A(double)
1150DEFN_CTORS_T_A(const char *)
1151DEFN_CTORS_T_A(const sc_fxval &)
1152DEFN_CTORS_T_A(const sc_fxval_fast &)
1153DEFN_CTORS_T_B(const sc_fxnum &)
1154DEFN_CTORS_T_B(const sc_fxnum_fast &)
1155
1156DEFN_CTORS_T_A(int64)
1157DEFN_CTORS_T_A(uint64)
1158DEFN_CTORS_T_A(const sc_int_base &)
1159DEFN_CTORS_T_A(const sc_uint_base &)
1160DEFN_CTORS_T_A(const sc_signed &)
1161DEFN_CTORS_T_A(const sc_unsigned &)
1162
1163#undef DEFN_CTORS_T_A
1164#undef DEFN_CTORS_T_B
1165
1166// copy constructor
1167inline sc_fix_fast::sc_fix_fast(const sc_fix_fast &a) :
1168        sc_fxnum_fast(a, a.type_params(), SC_TC_, sc_fxcast_switch(), 0)
1169{}
1170
1171// unary bitwise operators
1172inline const sc_fix_fast
1173sc_fix_fast::operator ~ () const
1174{
1175    SC_FXNUM_FAST_OBSERVER_READ_(*this)
1176    int iwl_c = iwl();
1177    int wl_c = wl();
1178    sc_fix_fast c(wl_c, iwl_c);
1179    for (int i = iwl_c - wl_c; i < iwl_c; ++i)
1180        c.set_bit(i, !get_bit(i));
1181    return sc_fix_fast(c, wl_c, iwl_c);
1182}
1183
1184// unary bitwise functions
1185inline void
1186b_not(sc_fix_fast &c, const sc_fix_fast &a)
1187{
1188    SC_FXNUM_FAST_OBSERVER_READ_(a)
1189    int iwl_c = c.iwl();
1190    for (int i = iwl_c - c.wl(); i < iwl_c; ++i)
1191        c.set_bit(i, !a.get_bit(i));
1192    c.cast();
1193    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
1194}
1195
1196// binary bitwise operators
1197#define DEFN_BIN_OP_T(op, op2, tp1, tp2) \
1198inline const sc_fix_fast \
1199operator op (const tp1 &a, const tp2 &b) \
1200{ \
1201    a.observer_read(); \
1202    b.observer_read(); \
1203    int iwl_a = a.iwl(); \
1204    int iwl_b = b.iwl(); \
1205    int iwl_c = sc_max(iwl_a, iwl_b); \
1206    int fwl_c = sc_max(a.wl() - iwl_a, b.wl() - iwl_b); \
1207    sc_fix_fast c(iwl_c + fwl_c, iwl_c); \
1208    for (int i = -fwl_c; i < iwl_c; ++i) \
1209        c.set_bit(i, a.get_bit(i) op2 b.get_bit(i)); \
1210    return sc_fix_fast(c, iwl_c + fwl_c, iwl_c); \
1211}
1212
1213DEFN_BIN_OP_T(&, &&, sc_fix_fast, sc_fix_fast)
1214DEFN_BIN_OP_T(|, ||, sc_fix_fast, sc_fix_fast)
1215DEFN_BIN_OP_T(^, !=, sc_fix_fast, sc_fix_fast)
1216
1217#undef DEFN_BIN_OP_T
1218
1219// binary bitwise functions
1220#define DEFN_BIN_FNC_T(fnc, op2, tp1, tp2) \
1221inline void \
1222fnc(sc_fix_fast &c, const tp1 &a, const tp2 &b) \
1223{ \
1224    a.observer_read(); \
1225    b.observer_read(); \
1226    int iwl_c = c.iwl(); \
1227    for (int i = iwl_c - c.wl(); i < iwl_c; ++i) \
1228        c.set_bit(i, a.get_bit(i) op2 b.get_bit(i)); \
1229    c.cast(); \
1230    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
1231}
1232
1233DEFN_BIN_FNC_T(b_and, &&, sc_fix_fast, sc_fix_fast)
1234DEFN_BIN_FNC_T(b_or, ||, sc_fix_fast, sc_fix_fast)
1235DEFN_BIN_FNC_T(b_xor, !=, sc_fix_fast, sc_fix_fast)
1236
1237#undef DEFN_BIN_FNC_T
1238
1239// assignment operators
1240inline sc_fix_fast &
1241sc_fix_fast::operator = (const sc_fix_fast &a)
1242{
1243    sc_fxnum_fast::operator = (a);
1244    return *this;
1245}
1246
1247#define DEFN_ASN_OP_T(op, tp) \
1248inline sc_fix_fast & \
1249sc_fix_fast::operator op (tp a) \
1250{ \
1251    sc_fxnum_fast::operator op(a); \
1252    return *this; \
1253}
1254
1255#define DEFN_ASN_OP_OTHER(op) \
1256DEFN_ASN_OP_T(op, int64) \
1257DEFN_ASN_OP_T(op, uint64) \
1258DEFN_ASN_OP_T(op, const sc_int_base &) \
1259DEFN_ASN_OP_T(op, const sc_uint_base &) \
1260DEFN_ASN_OP_T(op, const sc_signed &) \
1261DEFN_ASN_OP_T(op, const sc_unsigned &)
1262
1263#define DEFN_ASN_OP(op) \
1264DEFN_ASN_OP_T(op, int) \
1265DEFN_ASN_OP_T(op, unsigned int) \
1266DEFN_ASN_OP_T(op, long) \
1267DEFN_ASN_OP_T(op, unsigned long) \
1268DEFN_ASN_OP_T(op, float) \
1269DEFN_ASN_OP_T(op, double) \
1270DEFN_ASN_OP_T(op, const char *) \
1271DEFN_ASN_OP_T(op, const sc_fxval &) \
1272DEFN_ASN_OP_T(op, const sc_fxval_fast &) \
1273DEFN_ASN_OP_T(op, const sc_fxnum &) \
1274DEFN_ASN_OP_T(op, const sc_fxnum_fast &) \
1275DEFN_ASN_OP_OTHER(op)
1276
1277DEFN_ASN_OP(=)
1278
1279DEFN_ASN_OP(*=)
1280DEFN_ASN_OP(/=)
1281DEFN_ASN_OP(+=)
1282DEFN_ASN_OP(-=)
1283
1284DEFN_ASN_OP_T(<<=, int)
1285DEFN_ASN_OP_T(>>=, int)
1286
1287#undef DEFN_ASN_OP_T
1288#undef DEFN_ASN_OP_OTHER
1289#undef DEFN_ASN_OP
1290
1291#define DEFN_ASN_OP_T(op, op2, tp) \
1292inline sc_fix_fast & \
1293sc_fix_fast::operator op (const tp &b) \
1294{ \
1295    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
1296    b.observer_read(); \
1297    int iwl_c = iwl(); \
1298    for (int i = iwl_c - wl(); i < iwl_c; ++i) \
1299        set_bit(i, get_bit(i) op2 b.get_bit(i)); \
1300    cast(); \
1301    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
1302    return *this; \
1303}
1304
1305DEFN_ASN_OP_T(&=, &&, sc_fix)
1306DEFN_ASN_OP_T(&=, &&, sc_fix_fast)
1307DEFN_ASN_OP_T(|=, ||, sc_fix)
1308DEFN_ASN_OP_T(|=, ||, sc_fix_fast)
1309DEFN_ASN_OP_T(^=, !=, sc_fix)
1310DEFN_ASN_OP_T(^=, !=, sc_fix_fast)
1311
1312#undef DEFN_ASN_OP_T
1313
1314// auto-increment and auto-decrement
1315inline const sc_fxval_fast
1316sc_fix_fast::operator ++ (int)
1317{
1318    return sc_fxval_fast(sc_fxnum_fast::operator ++ (0));
1319}
1320
1321inline const sc_fxval_fast
1322sc_fix_fast::operator -- (int)
1323{
1324    return sc_fxval_fast(sc_fxnum_fast::operator -- (0));
1325}
1326
1327inline sc_fix_fast &
1328sc_fix_fast::operator ++ ()
1329{
1330    sc_fxnum_fast::operator ++ ();
1331    return *this;
1332}
1333
1334inline sc_fix_fast &
1335sc_fix_fast::operator -- ()
1336{
1337    sc_fxnum_fast::operator -- ();
1338    return *this;
1339}
1340
1341} // namespace sc_dt
1342
1343#endif // __SYSTEMC_EXT_DT_FX_SC_FIX_HH__
1344