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