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.cpp - 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 39// $Log: sc_fxnum.cpp,v $ 40// Revision 1.3 2011/01/19 18:57:40 acg 41// Andy Goodrich: changes for IEEE_1666_2011. 42// 43// Revision 1.2 2010/12/07 20:09:08 acg 44// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix 45// 46// Revision 1.1.1.1 2006/12/15 20:20:04 acg 47// SystemC 2.3 48// 49// Revision 1.3 2006/01/13 18:53:57 acg 50// Andy Goodrich: added $Log command so that CVS comments are reproduced in 51// the source. 52// 53 54#include <math.h> 55 56#include "sysc/datatypes/fx/sc_fxnum.h" 57 58 59namespace sc_dt 60{ 61 62// ---------------------------------------------------------------------------- 63// CLASS : sc_fxnum_bitref 64// 65// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. 66// ---------------------------------------------------------------------------- 67 68bool 69sc_fxnum_bitref::get() const 70{ 71 return m_num.get_bit( m_idx ); 72} 73 74void 75sc_fxnum_bitref::set( bool high ) 76{ 77 m_num.set_bit( m_idx, high ); 78} 79 80 81// print or dump content 82 83void 84sc_fxnum_bitref::print( ::std::ostream& os ) const 85{ 86 os << get(); 87} 88 89void 90sc_fxnum_bitref::scan( ::std::istream& is ) 91{ 92 bool b; 93 is >> b; 94 *this = b; 95} 96 97void 98sc_fxnum_bitref::dump( ::std::ostream& os ) const 99{ 100 os << "sc_fxnum_bitref" << ::std::endl; 101 os << "(" << ::std::endl; 102 os << "num = "; 103 m_num.dump( os ); 104 os << "idx = " << m_idx << ::std::endl; 105 os << ")" << ::std::endl; 106} 107 108 109// ---------------------------------------------------------------------------- 110// CLASS : sc_fxnum_fast_bitref 111// 112// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. 113// ---------------------------------------------------------------------------- 114 115bool 116sc_fxnum_fast_bitref::get() const 117{ 118 return m_num.get_bit( m_idx ); 119} 120 121void 122sc_fxnum_fast_bitref::set( bool high ) 123{ 124 m_num.set_bit( m_idx, high ); 125} 126 127 128// print or dump content 129 130void 131sc_fxnum_fast_bitref::print( ::std::ostream& os ) const 132{ 133 os << get(); 134} 135 136void 137sc_fxnum_fast_bitref::scan( ::std::istream& is ) 138{ 139 bool b; 140 is >> b; 141 *this = b; 142} 143 144void 145sc_fxnum_fast_bitref::dump( ::std::ostream& os ) const 146{ 147 os << "sc_fxnum_fast_bitref" << ::std::endl; 148 os << "(" << ::std::endl; 149 os << "num = "; 150 m_num.dump( os ); 151 os << "idx = " << m_idx << ::std::endl; 152 os << ")" << ::std::endl; 153} 154 155 156// ---------------------------------------------------------------------------- 157// CLASS : sc_fxnum_subref 158// 159// Proxy class for part-selection in class sc_fxnum, 160// behaves like sc_bv_base. 161// ---------------------------------------------------------------------------- 162 163bool 164sc_fxnum_subref::get() const 165{ 166 return m_num.get_slice( m_from, m_to, m_bv ); 167} 168 169bool 170sc_fxnum_subref::set() 171{ 172 return m_num.set_slice( m_from, m_to, m_bv ); 173} 174 175 176// print or dump content 177 178void 179sc_fxnum_subref::print( ::std::ostream& os ) const 180{ 181 get(); 182 m_bv.print( os ); 183} 184 185void 186sc_fxnum_subref::scan( ::std::istream& is ) 187{ 188 m_bv.scan( is ); 189 set(); 190} 191 192void 193sc_fxnum_subref::dump( ::std::ostream& os ) const 194{ 195 os << "sc_fxnum_subref" << ::std::endl; 196 os << "(" << ::std::endl; 197 os << "num = "; 198 m_num.dump( os ); 199 os << "from = " << m_from << ::std::endl; 200 os << "to = " << m_to << ::std::endl; 201 os << ")" << ::std::endl; 202} 203 204 205// ---------------------------------------------------------------------------- 206// CLASS : sc_fxnum_fast_subref 207// 208// Proxy class for part-selection in class sc_fxnum_fast, 209// behaves like sc_bv_base. 210// ---------------------------------------------------------------------------- 211 212bool 213sc_fxnum_fast_subref::get() const 214{ 215 return m_num.get_slice( m_from, m_to, m_bv ); 216} 217 218bool 219sc_fxnum_fast_subref::set() 220{ 221 return m_num.set_slice( m_from, m_to, m_bv ); 222} 223 224 225// print or dump content 226 227void 228sc_fxnum_fast_subref::print( ::std::ostream& os ) const 229{ 230 get(); 231 m_bv.print( os ); 232} 233 234void 235sc_fxnum_fast_subref::scan( ::std::istream& is ) 236{ 237 m_bv.scan( is ); 238 set(); 239} 240 241void 242sc_fxnum_fast_subref::dump( ::std::ostream& os ) const 243{ 244 os << "sc_fxnum_fast_subref" << ::std::endl; 245 os << "(" << ::std::endl; 246 os << "num = "; 247 m_num.dump( os ); 248 os << "from = " << m_from << ::std::endl; 249 os << "to = " << m_to << ::std::endl; 250 os << ")" << ::std::endl; 251} 252 253 254// ---------------------------------------------------------------------------- 255// CLASS : sc_fxnum 256// 257// Base class for the fixed-point types; arbitrary precision. 258// ---------------------------------------------------------------------------- 259 260// explicit conversion to character string 261 262const std::string 263sc_fxnum::to_string() const 264{ 265 return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); 266} 267 268const std::string 269sc_fxnum::to_string( sc_numrep numrep ) const 270{ 271 return std::string( m_rep->to_string( numrep, -1, SC_F, &m_params ) ); 272} 273 274const std::string 275sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const 276{ 277 return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), 278 SC_F, &m_params ) ); 279} 280 281const std::string 282sc_fxnum::to_string( sc_fmt fmt ) const 283{ 284 return std::string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) ); 285} 286 287const std::string 288sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const 289{ 290 return std::string( m_rep->to_string( numrep, -1, fmt, &m_params ) ); 291} 292 293const std::string 294sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const 295{ 296 return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), 297 fmt, &m_params ) ); 298} 299 300 301const std::string 302sc_fxnum::to_dec() const 303{ 304 return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); 305} 306 307const std::string 308sc_fxnum::to_bin() const 309{ 310 return std::string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) ); 311} 312 313const std::string 314sc_fxnum::to_oct() const 315{ 316 return std::string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) ); 317} 318 319const std::string 320sc_fxnum::to_hex() const 321{ 322 return std::string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) ); 323} 324 325 326// print or dump content 327 328void 329sc_fxnum::print( ::std::ostream& os ) const 330{ 331 os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params ); 332} 333 334void 335sc_fxnum::scan( ::std::istream& is ) 336{ 337 std::string s; 338 is >> s; 339 *this = s.c_str(); 340} 341 342void 343sc_fxnum::dump( ::std::ostream& os ) const 344{ 345 os << "sc_fxnum" << ::std::endl; 346 os << "(" << ::std::endl; 347 os << "rep = "; 348 m_rep->dump( os ); 349 os << "params = "; 350 m_params.dump( os ); 351 os << "q_flag = " << m_q_flag << ::std::endl; 352 os << "o_flag = " << m_o_flag << ::std::endl; 353 // TO BE COMPLETED 354 // os << "observer = "; 355 // if( m_observer != 0 ) 356 // m_observer->dump( os ); 357 // else 358 // os << "0" << ::std::endl; 359 os << ")" << ::std::endl; 360} 361 362 363sc_fxnum_observer* 364sc_fxnum::lock_observer() const 365{ 366 SC_ASSERT_( m_observer != 0, "lock observer failed" ); 367 sc_fxnum_observer* tmp = m_observer; 368 m_observer = 0; 369 return tmp; 370} 371 372void 373sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const 374{ 375 SC_ASSERT_( observer_ != 0, "unlock observer failed" ); 376 m_observer = observer_; 377} 378 379 380// ---------------------------------------------------------------------------- 381// CLASS : sc_fxnum_fast 382// 383// Base class for the fixed-point types; limited precision. 384// ---------------------------------------------------------------------------- 385 386static 387void 388quantization( double& c, const scfx_params& params, bool& q_flag ) 389{ 390 int fwl = params.wl() - params.iwl(); 391 double scale = scfx_pow2( fwl ); 392 double val = scale * c; 393 double int_part; 394 double frac_part = modf( val, &int_part ); 395 396 q_flag = ( frac_part != 0.0 ); 397 398 if( q_flag ) 399 { 400 val = int_part; 401 402 switch( params.q_mode() ) 403 { 404 case SC_TRN: // truncation 405 { 406 if( c < 0.0 ) 407 val -= 1.0; 408 break; 409 } 410 case SC_RND: // rounding to plus infinity 411 { 412 if( frac_part >= 0.5 ) 413 val += 1.0; 414 else if( frac_part < -0.5 ) 415 val -= 1.0; 416 break; 417 } 418 case SC_TRN_ZERO: // truncation to zero 419 { 420 break; 421 } 422 case SC_RND_INF: // rounding to infinity 423 { 424 if( frac_part >= 0.5 ) 425 val += 1.0; 426 else if( frac_part <= -0.5 ) 427 val -= 1.0; 428 break; 429 } 430 case SC_RND_CONV: // convergent rounding 431 { 432 if( frac_part > 0.5 || 433 ( frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) 434 val += 1.0; 435 else if( frac_part < -0.5 || 436 ( frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) 437 val -= 1.0; 438 break; 439 } 440 case SC_RND_ZERO: // rounding to zero 441 { 442 if( frac_part > 0.5 ) 443 val += 1.0; 444 else if( frac_part < -0.5 ) 445 val -= 1.0; 446 break; 447 } 448 case SC_RND_MIN_INF: // rounding to minus infinity 449 { 450 if( frac_part > 0.5 ) 451 val += 1.0; 452 else if( frac_part <= -0.5 ) 453 val -= 1.0; 454 break; 455 } 456 default: 457 ; 458 } 459 } 460 461 val /= scale; 462 c = val; 463} 464 465static 466void 467overflow( double& c, const scfx_params& params, bool& o_flag ) 468{ 469 int iwl = params.iwl(); 470 int fwl = params.wl() - iwl; 471 double full_circle = scfx_pow2( iwl ); 472 double resolution = scfx_pow2( -fwl ); 473 double low, high; 474 if( params.enc() == SC_TC_ ) 475 { 476 high = full_circle / 2.0 - resolution; 477 if( params.o_mode() == SC_SAT_SYM ) 478 low = - high; 479 else 480 low = - full_circle / 2.0; 481 } 482 else 483 { 484 low = 0.0; 485 high = full_circle - resolution; 486 } 487 double val = c; 488 sc_fxval_fast c2(c); 489 490 bool under = ( val < low ); 491 bool over = ( val > high ); 492 493 o_flag = ( under || over ); 494 495 if( o_flag ) 496 { 497 switch( params.o_mode() ) 498 { 499 case SC_WRAP: // wrap-around 500 { 501 int n_bits = params.n_bits(); 502 503 if( n_bits == 0 ) 504 { 505 // wrap-around all 'wl' bits 506 val -= floor( val / full_circle ) * full_circle; 507 if( val > high ) 508 val -= full_circle; 509 } 510 else if( n_bits < params.wl() ) 511 { 512 double X = scfx_pow2( iwl - n_bits ); 513 514 // wrap-around least significant 'wl - n_bits' bits 515 val -= floor( val / X ) * X; 516 if( val > ( X - resolution ) ) 517 val -= X; 518 519 // saturate most significant 'n_bits' bits 520 if( under ) 521 val += low; 522 else 523 { 524 if( params.enc() == SC_TC_ ) 525 val += full_circle / 2.0 - X; 526 else 527 val += full_circle - X; 528 } 529 } 530 else 531 { 532 // saturate all 'wl' bits 533 if( under ) 534 val = low; 535 else 536 val = high; 537 } 538 break; 539 } 540 case SC_SAT: // saturation 541 case SC_SAT_SYM: // symmetrical saturation 542 { 543 if( under ) 544 val = low; 545 else 546 val = high; 547 break; 548 } 549 case SC_SAT_ZERO: // saturation to zero 550 { 551 val = 0.0; 552 break; 553 } 554 case SC_WRAP_SM: // sign magnitude wrap-around 555 { 556 SC_ERROR_IF_( params.enc() == SC_US_, 557 sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); 558 559 int n_bits = params.n_bits(); 560 561 if( n_bits == 0 ) 562 { 563 // invert conditionally 564 if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) ) 565 val = -val - resolution; 566 567 // wrap-around all 'wl' bits 568 val -= floor( val / full_circle ) * full_circle; 569 if( val > high ) 570 val -= full_circle; 571 } 572 else if( n_bits == 1 ) 573 { 574 // invert conditionally 575 if( c2.is_neg() != c2.get_bit( iwl - 1 ) ) 576 val = -val - resolution; 577 578 // wrap-around all 'wl' bits 579 val -= floor( val / full_circle ) * full_circle; 580 if( val > high ) 581 val -= full_circle; 582 } 583 else if( n_bits < params.wl() ) 584 { 585 // invert conditionally 586 if( c2.is_neg() == c2.get_bit( iwl - n_bits ) ) 587 val = -val - resolution; 588 589 double X = scfx_pow2( iwl - n_bits ); 590 591 // wrap-around least significant 'wl - n_bits' bits 592 val -= floor( val / X ) * X; 593 if( val > ( X - resolution ) ) 594 val -= X; 595 596 // saturate most significant 'n_bits' bits 597 if( under ) 598 val += low; 599 else 600 val += full_circle / 2.0 - X; 601 } else { 602 // saturate all 'wl' bits 603 if( under ) 604 val = low; 605 else 606 val = high; 607 } 608 break; 609 } 610 default: 611 ; 612 } 613 614 c = val; 615 } 616} 617 618 619void 620sc_fxnum_fast::cast() 621{ 622 scfx_ieee_double id( m_val ); 623 SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_); 624 625 if( m_params.cast_switch() == SC_ON ) 626 { 627 m_q_flag = false; 628 m_o_flag = false; 629 630 // check for special cases 631 632 if( id.is_zero() ) 633 { 634 if( id.negative() != 0 ) 635 m_val = -m_val; 636 return; 637 } 638 639 // perform casting 640 641 sc_dt::quantization( m_val, m_params, m_q_flag ); 642 sc_dt::overflow( m_val, m_params, m_o_flag ); 643 644 // check for special case: -0 645 646 id = m_val; 647 if( id.is_zero() && id.negative() != 0 ) { 648 m_val = -m_val; 649 } 650 651 // check for special case: NaN of Inf 652 653 if( id.is_nan() || id.is_inf() ) { 654 m_val = 0.0; 655 } 656 } 657} 658 659 660// defined in sc_fxval.cpp; 661extern 662const char* 663to_string( const scfx_ieee_double&, 664 sc_numrep, 665 int, 666 sc_fmt, 667 const scfx_params* = 0 ); 668 669 670// explicit conversion to character string 671 672const std::string 673sc_fxnum_fast::to_string() const 674{ 675 return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); 676} 677 678const std::string 679sc_fxnum_fast::to_string( sc_numrep numrep ) const 680{ 681 return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) ); 682} 683 684const std::string 685sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const 686{ 687 return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), 688 SC_F, &m_params ) ); 689} 690 691const std::string 692sc_fxnum_fast::to_string( sc_fmt fmt ) const 693{ 694 return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) ); 695} 696 697const std::string 698sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const 699{ 700 return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) ); 701} 702 703const std::string 704sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const 705{ 706 return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), 707 fmt, &m_params ) ); 708} 709 710 711const std::string 712sc_fxnum_fast::to_dec() const 713{ 714 return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); 715} 716 717const std::string 718sc_fxnum_fast::to_bin() const 719{ 720 return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) ); 721} 722 723const std::string 724sc_fxnum_fast::to_oct() const 725{ 726 return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) ); 727} 728 729const std::string 730sc_fxnum_fast::to_hex() const 731{ 732 return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) ); 733} 734 735 736// print or dump content 737 738void 739sc_fxnum_fast::print( ::std::ostream& os ) const 740{ 741 os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ); 742} 743 744void 745sc_fxnum_fast::scan( ::std::istream& is ) 746{ 747 std::string s; 748 is >> s; 749 *this = s.c_str(); 750} 751 752void 753sc_fxnum_fast::dump( ::std::ostream& os ) const 754{ 755 os << "sc_fxnum_fast" << ::std::endl; 756 os << "(" << ::std::endl; 757 os << "val = " << m_val << ::std::endl; 758 os << "params = "; 759 m_params.dump( os ); 760 os << "q_flag = " << m_q_flag << ::std::endl; 761 os << "o_flag = " << m_o_flag << ::std::endl; 762 // TO BE COMPLETED 763 // os << "observer = "; 764 // if( m_observer != 0 ) 765 // m_observer->dump( os ); 766 // else 767 // os << "0" << ::std::endl; 768 os << ")" << ::std::endl; 769} 770 771 772// internal use only; 773bool 774sc_fxnum_fast::get_bit( int i ) const 775{ 776 scfx_ieee_double id( m_val ); 777 if( id.is_zero() || id.is_nan() || id.is_inf() ) 778 return false; 779 780 // convert to two's complement 781 782 unsigned int m0 = id.mantissa0(); 783 unsigned int m1 = id.mantissa1(); 784 785 if( id.is_normal() ) 786 m0 += 1U << 20; 787 788 if( id.negative() != 0 ) 789 { 790 m0 = ~ m0; 791 m1 = ~ m1; 792 unsigned int tmp = m1; 793 m1 += 1U; 794 if( m1 <= tmp ) 795 m0 += 1U; 796 } 797 798 // get the right bit 799 800 int j = i - id.exponent(); 801 if( ( j += 20 ) >= 32 ) 802 return ( ( m0 & 1U << 31 ) != 0 ); 803 else if( j >= 0 ) 804 return ( ( m0 & 1U << j ) != 0 ); 805 else if( ( j += 32 ) >= 0 ) 806 return ( ( m1 & 1U << j ) != 0 ); 807 else 808 return false; 809} 810 811 812bool 813sc_fxnum_fast::set_bit( int i, bool high ) 814{ 815 scfx_ieee_double id( m_val ); 816 if( id.is_nan() || id.is_inf() ) 817 return false; 818 819 if( high ) 820 { 821 if( get_bit( i ) ) 822 return true; 823 824 if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) 825 m_val -= scfx_pow2( i ); 826 else 827 m_val += scfx_pow2( i ); 828 } 829 else 830 { 831 if( ! get_bit( i ) ) 832 return true; 833 834 if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) 835 m_val += scfx_pow2( i ); 836 else 837 m_val -= scfx_pow2( i ); 838 } 839 840 return true; 841} 842 843 844bool 845sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const 846{ 847 scfx_ieee_double id( m_val ); 848 if( id.is_nan() || id.is_inf() ) 849 return false; 850 851 // convert to two's complement 852 853 unsigned int m0 = id.mantissa0(); 854 unsigned int m1 = id.mantissa1(); 855 856 if( id.is_normal() ) 857 m0 += 1U << 20; 858 859 if( id.negative() != 0 ) 860 { 861 m0 = ~ m0; 862 m1 = ~ m1; 863 unsigned int tmp = m1; 864 m1 += 1U; 865 if( m1 <= tmp ) 866 m0 += 1U; 867 } 868 869 // get the bits 870 871 int l = j; 872 for( int k = 0; k < bv.length(); ++ k ) 873 { 874 bool b = false; 875 876 int n = l - id.exponent(); 877 if( ( n += 20 ) >= 32 ) 878 b = ( ( m0 & 1U << 31 ) != 0 ); 879 else if( n >= 0 ) 880 b = ( ( m0 & 1U << n ) != 0 ); 881 else if( ( n += 32 ) >= 0 ) 882 b = ( ( m1 & 1U << n ) != 0 ); 883 884 bv[k] = b; 885 886 if( i >= j ) 887 ++ l; 888 else 889 -- l; 890 } 891 892 return true; 893} 894 895bool 896sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv ) 897{ 898 scfx_ieee_double id( m_val ); 899 if( id.is_nan() || id.is_inf() ) 900 return false; 901 902 // set the bits 903 904 int l = j; 905 for( int k = 0; k < bv.length(); ++ k ) 906 { 907 if( bv[k].to_bool() ) 908 { 909 if( ! get_bit( l ) ) 910 { 911 if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) 912 m_val -= scfx_pow2( l ); 913 else 914 m_val += scfx_pow2( l ); 915 } 916 } 917 else 918 { 919 if( get_bit( l ) ) 920 { 921 if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) 922 m_val += scfx_pow2( l ); 923 else 924 m_val -= scfx_pow2( l ); 925 } 926 } 927 928 929 if( i >= j ) 930 ++ l; 931 else 932 -- l; 933 } 934 935 return true; 936} 937 938 939sc_fxnum_fast_observer* 940sc_fxnum_fast::lock_observer() const 941{ 942 SC_ASSERT_( m_observer != 0, "lock observer failed" ); 943 sc_fxnum_fast_observer* tmp = m_observer; 944 m_observer = 0; 945 return tmp; 946} 947 948void 949sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const 950{ 951 SC_ASSERT_( observer_ != 0, "unlock observer failed" ); 952 m_observer = observer_; 953} 954 955} // namespace sc_dt 956 957 958// Taf! 959