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