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