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