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_signal_int.cpp -- The sc_signal<sc_dt::sc_int<W> > implementations. 23 24 Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22 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: scx_signal_int.h,v $ 40Revision 1.1 2011/08/15 17:31:11 acg 41 Andy Goodrich: moved specialized signals from examples to this tree. 42 43Revision 1.2 2011/08/15 16:43:24 acg 44 Torsten Maehne: changes to remove unused argument warnings. 45 46Revision 1.1.1.1 2006/12/15 20:20:03 acg 47SystemC 2.3 48 49Revision 1.2 2005/12/26 20:11:14 acg 50Fixed up copyright. 51 52Revision 1.1.1.1 2005/12/19 23:16:42 acg 53First check in of SystemC 2.1 into its own archive. 54 55Revision 1.11 2005/04/11 19:05:36 acg 56Change to sc_clock for Microsoft VCC 6.0. Changes for namespaces 57 58Revision 1.10 2005/04/03 22:52:51 acg 59Namespace changes. 60 61Revision 1.9 2005/03/21 22:31:32 acg 62Changes to sc_core namespace. 63 64Revision 1.8 2004/09/27 21:01:59 acg 65Andy Goodrich - Forte Design Systems, Inc. 66 - This is specialized signal support that allows better use of signals 67 and ports whose target value is a SystemC native type. 68 69*/ 70 71 72 73#include <systemc> 74#include <typeinfo> 75 76/***************************************************************************** 77 78 sc_signal_uint.h -- The sc_signal<sc_dt::sc_int<W> > definitions. 79 80 Original Author: Andy Goodrich, Forte Design Systems, 2002-10-22 81 82 *****************************************************************************/ 83 84/***************************************************************************** 85 86 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 87 changes you are making here. 88 89 Name, Affiliation, Date: 90 Description of Modification: 91 92 *****************************************************************************/ 93 94/* 95$Log: scx_signal_int.h,v $ 96Revision 1.1 2011/08/15 17:31:11 acg 97 Andy Goodrich: moved specialized signals from examples to this tree. 98 99Revision 1.3 2011/08/15 16:43:24 acg 100 Torsten Maehne: changes to remove unused argument warnings. 101 102Revision 1.2 2011/06/28 21:23:02 acg 103 Andy Goodrich: merging of SCV tree. 104 105Revision 1.1.1.1 2006/12/15 20:20:03 acg 106SystemC 2.3 107 108Revision 1.2 2005/12/26 20:11:14 acg 109Fixed up copyright. 110 111Revision 1.1.1.1 2005/12/19 23:16:42 acg 112First check in of SystemC 2.1 into its own archive. 113 114Revision 1.21 2005/03/21 22:31:32 acg 115Changes to sc_core namespace. 116 117Revision 1.20 2005/01/10 17:51:58 acg 118Improvements. 119 120Revision 1.19 2004/11/09 00:11:26 acg 121Added support for sc_generic_base<T> in place of sc_concatref. sc_concatref 122now is derived from sc_generic_base<sc_concatref>. 123 124Revision 1.18 2004/09/27 21:01:59 acg 125Andy Goodrich - Forte Design Systems, Inc. 126 - This is specialized signal support that allows better use of signals 127 and ports whose target value is a SystemC native type. 128 129*/ 130 131 132#if !defined(SC_SIGNAL_INT_H) 133#define SC_SIGNAL_INT_H 134 135#if ( !defined(_MSC_VER) || _MSC_VER > 1200 ) 136# define SC_TEMPLATE template<int W> 137#else 138# define SC_TEMPLATE template<> template<int W> 139#endif 140 141 142// FORWARD REFERENCES AND USINGS: 143 144 145namespace sc_core { 146 147class sc_int_sigref; 148 149//============================================================================== 150// CLASS sc_int_part_if 151// 152// This class provides generic access to part selections for signals whose 153// data type is sc_dt::sc_int<W>. This class serves as the base class for the 154// sc_dt::sc_int<W> specialization of the sc_signal_in_if<T> class. The methods 155// in this class may be over-ridden individually, those that are not overridden 156// will produce an error message when called. The methods are used by the 157// sc_int_sigref class. 158// 159// Notes: 160// (1) Descriptions of the methods and operators in this class appear with 161// their implementations in sc_signal<sc_dt::sc_int<W> >. 162//============================================================================== 163class sc_int_part_if : virtual public sc_interface { 164 protected: 165 // constructor: 166 sc_int_part_if() {} 167 168 public: 169 // perform a part read. 170 virtual sc_dt::sc_int_base* part_read_target(); 171 virtual sc_dt::uint64 read_part( int left, int right ) const; 172 173 // perform a part write. 174 virtual sc_int_sigref& select_part( int left, int right ); 175 virtual void write_part( sc_dt::uint64 v, int left, int right ); 176 177 private: 178 sc_int_part_if( const sc_int_part_if& ); 179 sc_int_part_if& operator = ( const sc_int_part_if& ); 180}; 181 182 183//============================================================================== 184// CLASS sc_signal_in_if<sc_dt::sc_int<W> > 185// 186// This is the class specializations for the sc_signal_in_if<T> class to 187// provide additional features for sc_signal instances whose template is 188// sc_dt::sc_int<W>, including part access. 189// 190// Notes: 191// (1) Descriptions of the methods and operators in this class appear with 192// their implementations in sc_signal<sc_dt::sc_int<W> >. 193//============================================================================== 194template< int W > 195class sc_signal_in_if<sc_dt::sc_int<W> > : public sc_int_part_if { 196 friend class sc_int_sigref; 197 public: 198 typedef sc_signal_in_if<sc_dt::sc_int<W> > this_type; 199 200 // get the value changed event 201 virtual const sc_event& value_changed_event() const = 0; 202 203 204 // read the current value 205 virtual const sc_dt::sc_int<W>& read() const = 0; 206 207 // get a reference to the current value (for tracing) 208 virtual const sc_dt::sc_int<W>& get_data_ref() const = 0; 209 210 211 // was there a value changed event? 212 virtual bool event() const = 0; 213 214 protected: 215 // constructor 216 sc_signal_in_if() 217 {} 218 219 private: // disabled 220 sc_signal_in_if( const this_type& ); 221 this_type& operator = ( const this_type& ); 222}; 223 224//============================================================================= 225// CLASS : sc_int_sigref 226// 227// Proxy class for sc_signal_int bit and part selection. 228//============================================================================= 229class sc_int_sigref : public sc_dt::sc_int_subref_r 230{ 231 public: 232 sc_int_sigref() : sc_dt::sc_int_subref_r() {} 233 virtual ~sc_int_sigref() {} 234 virtual void concat_set(sc_dt::int64 src, int low_i); 235 virtual void concat_set(const sc_dt::sc_signed& src, int low_i); 236 virtual void concat_set(const sc_dt::sc_unsigned& src, int low_i); 237 virtual void concat_set(const sc_dt::sc_lv_base& src, int low_i); 238 virtual void concat_set(sc_dt::uint64 src, int low_i); 239 240 public: 241 inline void initialize( sc_int_part_if* if_p, int left_, int right_ ); 242 243 public: 244 inline void operator = ( sc_dt::uint64 v ); 245 inline void operator = ( const char* v ); 246 inline void operator = ( unsigned long v ); 247 inline void operator = ( long v ); 248 inline void operator = ( unsigned int v ); 249 inline void operator = ( int v ); 250 inline void operator = ( sc_dt::int64 v ); 251 inline void operator = ( double v ); 252 inline void operator = ( const sc_int_sigref& v ); 253 template<typename T> 254 inline void operator = ( const sc_dt::sc_generic_base<T>& v ); 255 inline void operator = ( const sc_dt::sc_signed& v ); 256 inline void operator = ( const sc_dt::sc_unsigned& v ); 257 inline void operator = ( const sc_dt::sc_bv_base& v ); 258 inline void operator = ( const sc_dt::sc_lv_base& v ); 259 260 public: 261 static sc_vpool<sc_int_sigref> m_pool; // Pool of objects to use. 262 263 protected: 264 sc_int_part_if* m_if_p; // Target for selection. 265 266 private: 267 268 // disabled 269 sc_int_sigref( const sc_int_sigref& a ); 270}; 271 272 273//============================================================================== 274// CLASS sc_signal<sc_dt::sc_int<W> > 275// 276// This class implements a signal whose value acts like an sc_dt::sc_int<W> data 277// value. This class is a specialization of the generic sc_signal class to 278// implement tailored support for the sc_dt::sc_int<W> class. 279// 280// Notes: 281// (1) Descriptions of the methods and operators in this class appear with 282// their implementations. 283//============================================================================== 284SC_TEMPLATE 285class sc_signal<sc_dt::sc_int<W> > : 286 public sc_signal_inout_if<sc_dt::sc_int<W> >, 287 public sc_prim_channel, 288 public sc_dt::sc_int<W> 289{ 290 public: // typedefs 291 typedef sc_signal<sc_dt::sc_int<W> > this_type; 292 293 public: // constructors and destructor: 294 inline sc_signal(); 295 explicit inline sc_signal(const char* name_); 296 virtual inline ~sc_signal(); 297 298 public: // base methods: 299 inline bool base_event() const; 300 inline const sc_dt::sc_int<W>& base_read() const; 301 inline const sc_event& base_value_changed_event() const; 302 inline void base_write( sc_dt::int64 value ); 303 304 public: // sc_prim_channel virtual methods: 305 virtual inline const char* kind() const; 306 virtual inline void update(); 307 308 public: // sc_interface virtual methods: 309 virtual inline const sc_event& default_event() const; 310 virtual inline void register_port( 311 sc_port_base& port_, const char* if_typename_ ); 312 313 public: // sc_int_part_if virtual methods: 314 virtual inline sc_dt::sc_int_base* part_read_target(); 315 virtual inline sc_dt::uint64 read_part(int left, int right) const; 316 virtual inline sc_int_sigref& select_part(int left, int right); 317 virtual inline void write_part(sc_dt::uint64 v, int left, int right); 318 319 public: // interface virtual methods: 320 virtual inline bool event() const; 321 virtual inline const sc_dt::sc_int<W>& get_data_ref() const; 322 virtual inline sc_signal<sc_dt::sc_int<W> >& get_signal() ; 323 virtual inline const sc_dt::sc_int<W>& read() const; 324 virtual inline const sc_event& value_changed_event() const; 325 virtual inline void write( const sc_in<sc_dt::sc_int<W> >& value ); 326 virtual inline void write( const sc_inout<sc_dt::sc_int<W> >& value ); 327 virtual inline void write( const sc_dt::sc_int<W>& value ); 328 329 public: // part selections: 330 inline sc_int_sigref& operator () ( int left, int right ); 331 inline sc_int_sigref& operator [] ( int bit ); 332 333 public: // operators: 334 inline void operator = ( const this_type& new_val ); 335 inline void operator = ( const char* new_val ); 336 inline void operator = ( sc_dt::uint64 new_val ); 337 inline void operator = ( sc_dt::int64 new_val ); 338 inline void operator = ( int new_val ); 339 inline void operator = ( long new_val ) ; 340 inline void operator = ( short new_val ) ; 341 inline void operator = ( unsigned int new_val ) ; 342 inline void operator = ( unsigned long new_val ); 343 inline void operator = ( unsigned short new_val ); 344 template<typename T> 345 inline void operator = ( const sc_dt::sc_generic_base<T>& new_val ); 346 inline void operator = ( const sc_dt::sc_signed& new_val ); 347 inline void operator = ( const sc_dt::sc_unsigned& new_val ); 348 inline void operator = ( const sc_dt::sc_bv_base& new_val ); 349 inline void operator = ( const sc_dt::sc_lv_base& new_val ); 350 351 // concatenation methods (we inherit length and gets from sc_dt::sc_int<W>): 352 353 virtual inline void concat_set(sc_dt::int64 src, int low_i); 354 virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i); 355 virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i); 356 virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i); 357 virtual inline void concat_set(sc_dt::uint64 src, int low_i); 358 359 protected: // debugging methods: 360 // #### void check_port(); 361 void check_writer(); 362 363 private: // Disabled operations that sc_dt::sc_int<W> supports: 364 sc_signal<sc_dt::sc_int<W> >& operator ++ (); // prefix 365 const sc_signal<sc_dt::sc_int<W> >& operator ++ (int); // postfix 366 sc_signal<sc_dt::sc_int<W> >& operator -- (); // prefix 367 const sc_signal<sc_dt::sc_int<W> >& operator -- (int); // postfix 368 sc_signal<sc_dt::sc_int<W> >& operator += (sc_dt::int_type); 369 sc_signal<sc_dt::sc_int<W> >& operator -= (sc_dt::int_type); 370 sc_signal<sc_dt::sc_int<W> >& operator *= (sc_dt::int_type); 371 sc_signal<sc_dt::sc_int<W> >& operator /= (sc_dt::int_type); 372 sc_signal<sc_dt::sc_int<W> >& operator %= (sc_dt::int_type); 373 sc_signal<sc_dt::sc_int<W> >& operator &= (sc_dt::int_type); 374 sc_signal<sc_dt::sc_int<W> >& operator |= (sc_dt::int_type); 375 sc_signal<sc_dt::sc_int<W> >& operator ^= (sc_dt::int_type); 376 377 protected: 378 mutable sc_event* m_changed_event_p; // Value changed event this object. 379 sc_dt::uint64 m_event_delta; // Delta cycle of last event. 380 sc_dt::int64 m_new_val; // New value for this object instance. 381 sc_port_base* m_output_p; // Single write port verify field. 382 sc_process_b* m_writer_p; // Single writer verify field. 383}; 384 385 386SC_TEMPLATE // Return true if a changed event happened in the last delta cycle. 387inline bool sc_signal<sc_dt::sc_int<W> >::base_event() const 388{ 389 return simcontext()->delta_count() == m_event_delta + 1; 390} 391 392 393SC_TEMPLATE // Return this object's sc_dt::sc_int<W> object instance. 394inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::base_read() const 395{ 396 return *this; 397} 398 399 400SC_TEMPLATE // Return the value changed event, allocating it if necessary. 401inline const sc_event& sc_signal<sc_dt::sc_int<W> >::base_value_changed_event() const 402{ 403 if ( !m_changed_event_p ) m_changed_event_p = new sc_event; 404 return *m_changed_event_p; 405} 406 407 408SC_TEMPLATE // Select a portion of a value. 409inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::select_part(int left, int right) 410{ 411 sc_int_sigref* result_p = sc_int_sigref::m_pool.allocate(); 412 result_p->initialize(this, left, right); 413 return *result_p; 414} 415 416 417SC_TEMPLATE // Write an sc_dt::uint64 value to this object instance. 418inline void sc_signal<sc_dt::sc_int<W> >::base_write( sc_dt::int64 value ) 419{ 420# if defined(DEBUG_SYSTEMC) 421 check_writer(); 422# endif 423 m_new_val = value; 424 request_update(); 425} 426 427//------------------------------------------------------------------------------ 428//"sc_signal<sc_dt::sc_int<W> >::check_writer" 429// 430// This method checks to see if there is more than one writer for this 431// object instance by keeping track of the process performing the write. 432//------------------------------------------------------------------------------ 433SC_TEMPLATE 434inline void sc_signal<sc_dt::sc_int<W> >::check_writer() 435{ 436 sc_process_b* writer_p = sc_get_curr_process_handle(); 437 if( m_writer_p == 0 ) 438 { 439 m_writer_p = writer_p; 440 } 441 else if( m_writer_p != writer_p ) 442 { 443 sc_signal_invalid_writer( name(), kind(), 444 m_writer_p->name(), writer_p->name() ); 445 } 446} 447 448 449//------------------------------------------------------------------------------ 450//"sc_signal<sc_dt::sc_int<W> >::concat_set" 451// 452// These virtual methods allow value assignments to this object instance 453// from various sources. The position within the supplied source of the 454// low order bit for this object instance's value is low_i. 455// src = source value. 456// low_i = bit within src to serve as low order bit of this object 457// instance's value. 458//------------------------------------------------------------------------------ 459SC_TEMPLATE 460inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::int64 src, int low_i) 461{ 462 if ( low_i < 64 ) 463 { 464 base_write(src >> low_i); 465 } 466 else 467 { 468 base_write( src >> 63 ); 469 } 470} 471 472SC_TEMPLATE 473inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_lv_base& src, int low_i) 474{ 475 sc_dt::sc_unsigned tmp(src.length()); 476 tmp = src >> low_i; 477 base_write( tmp.to_int64() ); 478} 479 480SC_TEMPLATE 481inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_signed& src, int low_i) 482{ 483 base_write( (src >> low_i).to_int64()); 484} 485 486SC_TEMPLATE 487inline void sc_signal<sc_dt::sc_int<W> >::concat_set(const sc_dt::sc_unsigned& src, int low_i) 488{ 489 base_write( (src >> low_i).to_int64()); 490} 491 492SC_TEMPLATE 493inline void sc_signal<sc_dt::sc_int<W> >::concat_set(sc_dt::uint64 src, int low_i) 494{ 495 base_write( ( low_i < 64 ) ? src >> low_i : 0 ); 496} 497 498 499 500SC_TEMPLATE // Return the default event for this object instance. 501inline const sc_event& sc_signal<sc_dt::sc_int<W> >::default_event() const 502 { return base_value_changed_event(); } 503 504 505SC_TEMPLATE // Return true if a changed event happened in the last delta cycle. 506inline bool sc_signal<sc_dt::sc_int<W> >::event() const 507 { return base_event(); } 508 509 510SC_TEMPLATE // Return a reference to the value of this object instance. 511inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::get_data_ref() const 512 { return *this; } 513 514 515SC_TEMPLATE // Return a pointer to this object instance. 516inline sc_signal<sc_dt::sc_int<W> >& sc_signal<sc_dt::sc_int<W> >::get_signal() 517 { return *this; } 518 519 520SC_TEMPLATE // Return a kind value of "sc_signal". 521inline const char* sc_signal<sc_dt::sc_int<W> >::kind() const 522{ 523 return "sc_signal"; 524} 525 526 527//------------------------------------------------------------------------------ 528//"sc_signal_uint::operator () 529// 530// This operator returns a part selection of this object instance. 531// left = left-hand bit of the selection. 532// right = right-hand bit of the selection. 533//------------------------------------------------------------------------------ 534SC_TEMPLATE 535inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator () (int left, int right) 536{ 537 sc_int_sigref* result_p; // Value to return. 538 539 result_p = sc_int_sigref::m_pool.allocate(); 540 result_p->initialize(this, left, right); 541 return *result_p; 542} 543 544 545//------------------------------------------------------------------------------ 546//"sc_signal_uint::operator []" 547// 548// This operator returns a bit selection of this object instance. 549// i = bit to be selected. 550//------------------------------------------------------------------------------ 551SC_TEMPLATE 552inline sc_int_sigref& sc_signal<sc_dt::sc_int<W> >::operator [] ( int bit ) 553{ 554 return operator () (bit,bit); 555} 556 557 558SC_TEMPLATE 559inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const this_type& new_val ) 560 { base_write( (sc_dt::int64)new_val ); } 561 562SC_TEMPLATE 563inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const char* new_val ) 564 { m_new_val = sc_dt::sc_int<64>(new_val); request_update(); } 565 566SC_TEMPLATE 567inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::uint64 new_val ) 568 { base_write((sc_dt::int64)new_val); } 569 570SC_TEMPLATE 571inline void sc_signal<sc_dt::sc_int<W> >::operator = ( sc_dt::int64 new_val ) 572 { base_write(new_val); } 573 574SC_TEMPLATE 575inline void sc_signal<sc_dt::sc_int<W> >::operator = ( int new_val ) 576 { base_write((sc_dt::int64)new_val); } 577 578SC_TEMPLATE 579inline void sc_signal<sc_dt::sc_int<W> >::operator = ( long new_val ) 580 { base_write((sc_dt::int64)new_val); } 581 582SC_TEMPLATE 583inline void sc_signal<sc_dt::sc_int<W> >::operator = ( short new_val ) 584 { base_write((sc_dt::int64)new_val); } 585 586SC_TEMPLATE 587inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned int new_val ) 588 { base_write((sc_dt::int64)new_val); } 589 590SC_TEMPLATE 591inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned long new_val ) 592 { base_write((sc_dt::int64)new_val); } 593 594SC_TEMPLATE 595inline void sc_signal<sc_dt::sc_int<W> >::operator = ( unsigned short new_val ) 596 { base_write((sc_dt::int64)new_val); } 597 598 599SC_TEMPLATE 600template<typename T> 601inline void sc_signal<sc_dt::sc_int<W> >::operator = ( 602 const sc_dt::sc_generic_base<T>& new_val ) 603 { base_write(new_val->to_int64()); } 604 605SC_TEMPLATE 606inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_signed& new_val ) 607 { base_write(new_val.to_int64()); } 608 609SC_TEMPLATE 610inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_unsigned& new_val ) 611 { base_write(new_val.to_int64()); } 612 613SC_TEMPLATE 614inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_bv_base& new_val ) 615 { base_write( (sc_dt::sc_int<W>)new_val ); } 616 617SC_TEMPLATE 618inline void sc_signal<sc_dt::sc_int<W> >::operator = ( const sc_dt::sc_lv_base& new_val ) 619 { base_write( (sc_dt::sc_int<W>)new_val ); } 620 621 622SC_TEMPLATE 623inline sc_dt::sc_int_base* sc_signal<sc_dt::sc_int<W> >::part_read_target() 624 { return this; } 625 626 627SC_TEMPLATE 628inline const sc_dt::sc_int<W>& sc_signal<sc_dt::sc_int<W> >::read() const 629 { return *this; } 630 631 632SC_TEMPLATE // Read a portion of a value. 633inline sc_dt::uint64 sc_signal<sc_dt::sc_int<W> >::read_part( int left, int right ) const 634{ 635 // This pointer required for HP aCC. 636 return (this->m_val & ~sc_dt::mask_int[left][right]) >> right; 637} 638 639SC_TEMPLATE 640inline void sc_signal<sc_dt::sc_int<W> >::register_port( 641 sc_port_base& port_, const char* if_typename_ ) 642{ 643# ifdef DEBUG_SYSTEMC 644 std::string nm( if_typename_ ); 645 if( nm == typeid( sc_signal_inout_if<sc_dt::sc_int<W> > ).name() ) 646 { 647 if( m_output_p != 0 ) 648 { 649 sc_signal_invalid_writer( name(), kind(), 650 m_output_p->name(), port_.name() ); 651 } 652 m_output_p = &port_; 653 } 654# else 655 if ( &port_ && if_typename_ ) {} // Silence unused args warning. 656# endif 657} 658 659 660SC_TEMPLATE // Autogenerated name object instance constructor. 661inline sc_signal<sc_dt::sc_int<W> >::sc_signal() : 662 sc_prim_channel(sc_gen_unique_name( "signal" )), 663 m_changed_event_p(0), 664 m_output_p(0), 665 m_writer_p(0) 666{ } 667 668 669SC_TEMPLATE // Explicitly named object instance constructor. 670inline sc_signal<sc_dt::sc_int<W> >::sc_signal(const char* name_) : 671 sc_prim_channel(name_), 672 m_changed_event_p(0), 673 m_output_p(0), 674 m_writer_p(0) 675{ } 676 677 678SC_TEMPLATE // Object instance destructor. 679inline sc_signal<sc_dt::sc_int<W> >::~sc_signal() 680{ 681 if ( m_changed_event_p ) delete m_changed_event_p; 682} 683 684 685SC_TEMPLATE // Update the current value from new value. 686inline void sc_signal<sc_dt::sc_int<W> >::update() 687{ 688 if ( m_changed_event_p ) 689 { 690 // This pointer required for HP aCC. 691 sc_dt::int64 old_val = this->m_val; 692 sc_dt::sc_int_base::operator = (m_new_val); 693 if ( old_val != this->m_val ) 694 { 695 m_changed_event_p->notify_delayed(); 696 m_event_delta = simcontext()->delta_count(); 697 } 698 } 699 else 700 { 701 sc_dt::sc_int_base::operator = (m_new_val); 702 } 703} 704 705 706SC_TEMPLATE // Return the value changed event. 707inline const sc_event& sc_signal<sc_dt::sc_int<W> >::value_changed_event() const 708 { return base_value_changed_event(); } 709 710 711SC_TEMPLATE // Write a sc_in<sc_dt::sc_int<W> > value to this object instance. 712inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_in<sc_dt::sc_int<W> >& value ) 713 { base_write( value.operator sc_dt::int64 () ); } 714 715 716SC_TEMPLATE // Write a sc_inout<sc_dt::sc_int<W> > value to this object instance. 717inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_inout<sc_dt::sc_int<W> >& value ) 718 { base_write( value.operator sc_dt::int64 () ); } 719 720 721SC_TEMPLATE // Write a sc_dt::sc_int<W> value to this object instance. 722inline void sc_signal<sc_dt::sc_int<W> >::write( const sc_dt::sc_int<W>& value ) 723 { base_write( value); } 724 725 726SC_TEMPLATE // Write a portion of a value. If this is the first write in 727 // a delta cycle we copy the existing value before setting the bits. 728inline void sc_signal<sc_dt::sc_int<W> >::write_part( sc_dt::uint64 v, int left, int right ) 729{ 730 sc_dt::int64 new_v; // New value. 731 sc_dt::uint64 keep; // Keep mask value. 732 733 keep = sc_dt::mask_int[left][right]; 734 new_v = (m_new_val & keep) | ((v << right) & ~keep); 735 if ( m_new_val != new_v ) request_update(); 736 m_new_val = new_v; 737} 738 739 740//============================================================================== 741// CLASS sc_in<sc_dt::sc_int<W> > 742// 743// This class implements an input port whose target acts like an sc_dt::sc_int<W> data 744// value. This class is a specialization of the generic sc_in class to 745// implement tailored support for the sc_dt::sc_int<W> class. 746//============================================================================== 747SC_TEMPLATE 748class sc_in<sc_dt::sc_int<W> > : 749 public sc_port<sc_signal_in_if<sc_dt::sc_int<W> >, 1>, 750 public sc_dt::sc_value_base 751{ 752 public: 753 754 // typedefs 755 756 typedef sc_dt::sc_int<W> data_type; 757 typedef sc_signal_in_if<sc_dt::sc_int<W> > if_type; 758 typedef sc_port<if_type,1> base_type; 759 typedef sc_in<sc_dt::sc_int<W> > this_type; 760 761 typedef if_type in_if_type; 762 typedef base_type in_port_type; 763 typedef sc_signal_inout_if<sc_dt::sc_int<W> > inout_if_type; 764 typedef sc_inout<sc_dt::sc_int<W> > inout_port_type; 765 766 public: 767 768 // bind methods and operators: 769 770 void bind( const in_if_type& interface_ ) 771 { sc_port_base::bind( const_cast<in_if_type&>( interface_) );} 772 void operator () ( const in_if_type& interface_ ) 773 { sc_port_base::bind( const_cast<in_if_type&>( interface_) );} 774 void bind( in_port_type& parent_ ) 775 { sc_port_base::bind(parent_);} 776 void operator () ( in_port_type& parent_ ) 777 { sc_port_base::bind(parent_);} 778 void bind( inout_port_type& parent_ ) 779 { sc_port_base::bind(parent_);} 780 void operator () ( inout_port_type& parent_ ) 781 { sc_port_base::bind(parent_);} 782 783 protected: 784 // called by pbind (for internal use only) 785 virtual inline int vbind( sc_interface& interface_ ) 786 { 787 return sc_port_b<if_type>::vbind( interface_ ); 788 } 789 virtual inline int vbind( sc_port_base& parent_ ) 790 { 791 in_port_type* in_parent = dynamic_cast<in_port_type*>( &parent_ ); 792 if( in_parent != 0 ) { 793 sc_port_base::bind( *in_parent ); 794 return 0; 795 } 796 inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ ); 797 if( inout_parent != 0 ) { 798 sc_port_base::bind( *inout_parent ); 799 return 0; 800 } 801 // type mismatch 802 return 2; 803 } 804 805 806 // constructors 807 808 public: 809 sc_in() 810 : base_type(), m_traces( 0 ) 811 {} 812 813 explicit sc_in( const char* name_ ) 814 : base_type( name_ ), m_traces( 0 ) 815 {} 816 817 explicit sc_in( const in_if_type& interface_ ) 818 : base_type( const_cast<in_if_type&>( interface_ ) ), m_traces( 0 ) 819 {} 820 821 sc_in( const char* name_, const in_if_type& interface_ ) 822 : base_type( name_, const_cast<in_if_type&>( interface_ ) ), m_traces( 0 ) 823 {} 824 825 explicit sc_in( in_port_type& parent_ ) 826 : base_type( parent_ ), m_traces( 0 ) 827 {} 828 829 sc_in( const char* name_, in_port_type& parent_ ) 830 : base_type( name_, parent_ ), m_traces( 0 ) 831 {} 832 833 explicit sc_in( inout_port_type& parent_ ) 834 : base_type(), m_traces( 0 ) 835 { sc_port_base::bind( parent_ ); } 836 837 sc_in( const char* name_, inout_port_type& parent_ ) 838 : base_type( name_ ), m_traces( 0 ) 839 { sc_port_base::bind( parent_ ); } 840 841 sc_in( this_type& parent_ ) 842 : base_type( parent_ ), m_traces( 0 ) 843 {} 844 845 sc_in( const char* name_, this_type& parent_ ) 846 : base_type( name_, parent_ ), m_traces( 0 ) 847 {} 848 849 850 // destructor 851 852 virtual inline ~sc_in() 853 { 854 remove_traces(); 855 } 856 857 // bit and part selection 858 859 sc_dt::sc_int_bitref_r operator [] ( int i ) const 860 { return (*this)->read()[i]; } 861 sc_dt::sc_int_bitref_r bit( int i ) const 862 { return (*this)->read()[i]; } 863 sc_dt::sc_int_subref_r operator () ( int left, int right ) const 864 { return (*this)->read()(left,right); } 865 sc_dt::sc_int_subref_r range( int left, int right ) const 866 { return (*this)->read()(left,right); } 867 868 869 // interface access shortcut methods 870 871 // get the default event 872 873 const sc_event& default_event() const 874 { return (*this)->value_changed_event(); } 875 876 877 // get the value changed event 878 879 const sc_event& value_changed_event() const 880 { return (*this)->value_changed_event(); } 881 882 883 // read the current value 884 885 const sc_dt::sc_int<W>& read() const 886 { return (*this)->read(); } 887 888 operator sc_dt::int64 () const 889 { return (sc_dt::int64)(*this)->read(); } 890 891 // was there a value changed event? 892 893 bool event() const 894 { return (*this)->event(); } 895 896 897 // (other) event finder method(s) 898 899 sc_event_finder& value_changed() const 900 { 901 return *new sc_event_finder_t<in_if_type>( 902 *this, &in_if_type::value_changed_event ); 903 } 904 905 906 907 // reduction methods: 908 909 inline bool and_reduce() const 910 { return (*this)->read().and_reduce(); } 911 inline bool nand_reduce() const 912 { return (*this)->read().nand_reduce(); } 913 inline bool nor_reduce() const 914 { return (*this)->read().nor_reduce(); } 915 inline bool or_reduce() const 916 { return (*this)->read().or_reduce(); } 917 inline bool xnor_reduce() const 918 { return (*this)->read().xnor_reduce(); } 919 inline bool xor_reduce() const 920 { return (*this)->read().xor_reduce(); } 921 922 923 // called when elaboration is done 924 /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */ 925 /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */ 926 927 virtual inline void end_of_elaboration() 928 { 929 if( m_traces != 0 ) { 930 for( unsigned int i = 0; i < m_traces->size(); ++ i ) { 931 sc_trace_params* p = (*m_traces)[i]; 932 sc_trace( p->tf, read(), p->name ); 933 } 934 remove_traces(); 935 } 936 } 937 938 virtual inline const char* kind() const 939 { return "sc_in"; } 940 941 942 // called by sc_trace 943 void add_trace( sc_trace_file* tf_, const std::string& name_ ) const 944 { 945 if( tf_ != 0 ) { 946 if( m_traces == 0 ) { 947 m_traces = new sc_trace_params_vec; 948 } 949 m_traces->push_back( new sc_trace_params( tf_, name_ ) ); 950 } 951 } 952 953 954 // concatenation methods 955 956 virtual inline int concat_length(bool* xz_present_p) const 957 { return (*this)->read().concat_length( xz_present_p ); } 958 virtual inline sc_dt::uint64 concat_get_uint64() const 959 { return (*this)->read().concat_get_uint64(); } 960 virtual 961 inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const 962 { return (*this)->read().concat_get_ctrl(dst_p, low_i); } 963 virtual 964 inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const 965 { return (*this)->read().concat_get_data(dst_p, low_i); } 966 967 protected: 968 void remove_traces() const 969 { 970 if( m_traces != 0 ) { 971 for( int i = m_traces->size() - 1; i >= 0; -- i ) { 972 delete (*m_traces)[i]; 973 } 974 delete m_traces; 975 m_traces = 0; 976 } 977 } 978 979 mutable sc_trace_params_vec* m_traces; 980 981 982 private: 983 984 // disabled 985 sc_in( const sc_in<sc_dt::sc_int<W> >& ); 986 sc_in<sc_dt::sc_int<W> >& operator = ( const sc_in<sc_dt::sc_int<W> >& ); 987 988#ifdef __GNUC__ 989 // Needed to circumvent a problem in the g++-2.95.2 compiler: 990 // This unused variable forces the compiler to instantiate 991 // an object of T template so an implicit conversion from 992 // read() to a C++ intrinsic data type will work. 993 static data_type dummy; 994#endif 995 996}; 997 998 999 1000SC_TEMPLATE 1001inline std::ostream& operator << (std::ostream& os, const sc_in<sc_dt::sc_int<W> >& a) 1002{ 1003 a.read().print( os ); 1004 return os; 1005} 1006 1007 1008//============================================================================== 1009// CLASS sc_inout<sc_dt::sc_int<W> > 1010// 1011// This class implements an input/output port whose target acts like an 1012// sc_dt::sc_int<W> data value. It is derived from the sc_int_in. This class is a 1013// specialization of the generic sc_inout class to implement tailored support 1014// for the sc_dt::sc_int<W> class. 1015//============================================================================== 1016SC_TEMPLATE 1017class sc_inout<sc_dt::sc_int<W> > : 1018 public sc_port<sc_signal_inout_if<sc_dt::sc_int<W> >, 1>, 1019 public sc_dt::sc_value_base 1020{ 1021 public: 1022 1023 // typedefs 1024 1025 typedef sc_dt::sc_int<W> data_type; 1026 typedef sc_signal_inout_if<sc_dt::sc_int<W> > if_type; 1027 typedef sc_port<if_type,1> base_type; 1028 typedef sc_inout<sc_dt::sc_int<W> > this_type; 1029 1030 typedef if_type inout_if_type; 1031 typedef base_type inout_port_type; 1032 1033 public: 1034 1035 // bind methods and operators: 1036 1037 void bind( const inout_if_type& interface_ ) 1038 { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); } 1039 void operator () ( const inout_if_type& interface_ ) 1040 { sc_port_base::bind( const_cast<inout_if_type&>( interface_) ); } 1041 void bind( inout_port_type& parent_ ) 1042 { sc_port_base::bind(parent_); } 1043 void operator () ( inout_port_type& parent_ ) 1044 { sc_port_base::bind(parent_); } 1045 1046 protected: 1047 // called by pbind (for internal use only) 1048 virtual inline int vbind( sc_interface& interface_ ) 1049 { 1050 return sc_port_b<if_type>::vbind( interface_ ); 1051 } 1052 virtual inline int vbind( sc_port_base& parent_ ) 1053 { 1054 inout_port_type* inout_parent = dynamic_cast<inout_port_type*>( &parent_ ); 1055 if( inout_parent != 0 ) { 1056 sc_port_base::bind( *inout_parent ); 1057 return 0; 1058 } 1059 // type mismatch 1060 return 2; 1061 } 1062 1063 1064 // constructors 1065 1066 public: 1067 sc_inout() 1068 : base_type(), m_init_val_p(0), m_traces( 0 ) 1069 {} 1070 1071 explicit sc_inout( const char* name_ ) 1072 : base_type( name_ ), m_init_val_p(0), m_traces( 0 ) 1073 {} 1074 1075 explicit sc_inout( inout_if_type& interface_ ) 1076 : base_type( interface_ ), m_init_val_p(0), m_traces( 0 ) 1077 {} 1078 1079 sc_inout( const char* name_, inout_if_type& interface_ ) 1080 : base_type( name_, interface_ ), m_init_val_p(0), m_traces( 0 ) 1081 {} 1082 1083 explicit sc_inout( inout_port_type& parent_ ) 1084 : base_type( parent_ ), m_init_val_p(0), m_traces( 0 ) 1085 {} 1086 1087 sc_inout( const char* name_, inout_port_type& parent_ ) 1088 : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 ) 1089 {} 1090 1091 sc_inout( this_type& parent_ ) 1092 : base_type( parent_ ), m_init_val_p(0), m_traces( 0 ) 1093 {} 1094 1095 sc_inout( const char* name_, this_type& parent_ ) 1096 : base_type( name_, parent_ ), m_init_val_p(0), m_traces( 0 ) 1097 {} 1098 1099 1100 // destructor 1101 1102 virtual inline ~sc_inout() 1103 { 1104 remove_traces(); 1105 } 1106 1107 // bit and part selection 1108 1109 sc_dt::sc_int_bitref_r operator [] ( int i ) const 1110 { return (*this)->read()[i]; } 1111 sc_dt::sc_int_bitref_r bit( int i ) const 1112 { return (*this)->read()[i]; } 1113 sc_int_sigref& operator [] ( int i ) 1114 { return (*this)->select_part(i,i); } 1115 sc_int_sigref& bit( int i ) 1116 { return (*this)->select_part(i,i); } 1117 sc_dt::sc_int_subref_r operator () ( int left, int right ) const 1118 { return (*this)->read()(left,right); } 1119 sc_dt::sc_int_subref_r range( int left, int right ) const 1120 { return (*this)->read()(left,right); } 1121 sc_int_sigref& operator () ( int left, int right ) 1122 { return (*this)->select_part(left,right); } 1123 sc_int_sigref& range( int left, int right ) 1124 { return (*this)->select_part(left,right); } 1125 1126 1127 // interface access shortcut methods 1128 1129 // get the default event 1130 1131 const sc_event& default_event() const 1132 { return (*this)->value_changed_event(); } 1133 1134 1135 // get the value changed event 1136 1137 const sc_event& value_changed_event() const 1138 { return (*this)->value_changed_event(); } 1139 1140 1141 // read the current value 1142 1143 const sc_dt::sc_int<W>& read() const 1144 { return (*this)->read(); } 1145 1146 operator sc_dt::int64 () const 1147 { return (sc_dt::int64)(*this)->read(); } 1148 1149 // was there a value changed event? 1150 1151 bool event() const 1152 { return (*this)->event(); } 1153 1154 1155 // (other) event finder method(s) 1156 1157 sc_event_finder& value_changed() const 1158 { 1159 return *new sc_event_finder_t<inout_if_type>( 1160 *this, &inout_if_type::value_changed_event ); 1161 } 1162 1163 1164 1165 // reduction methods: 1166 1167 inline bool and_reduce() const 1168 { return (*this)->read().and_reduce(); } 1169 inline bool nand_reduce() const 1170 { return (*this)->read().nand_reduce(); } 1171 inline bool nor_reduce() const 1172 { return (*this)->read().nor_reduce(); } 1173 inline bool or_reduce() const 1174 { return (*this)->read().or_reduce(); } 1175 inline bool xnor_reduce() const 1176 { return (*this)->read().xnor_reduce(); } 1177 inline bool xor_reduce() const 1178 { return (*this)->read().xor_reduce(); } 1179 1180 1181 // called when elaboration is done 1182 /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */ 1183 /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */ 1184 1185 virtual inline void end_of_elaboration() 1186 { 1187 if( m_init_val_p != 0 ) { 1188 (*this)->write( (sc_dt::int64) *m_init_val_p ); 1189 delete m_init_val_p; 1190 m_init_val_p = 0; 1191 } 1192 if( m_traces != 0 ) { 1193 for( unsigned int i = 0; i < m_traces->size(); ++ i ) { 1194 sc_trace_params* p = (*m_traces)[i]; 1195 sc_trace( p->tf, read(), p->name ); 1196 } 1197 remove_traces(); 1198 } 1199 } 1200 1201 virtual inline const char* kind() const 1202 { return "sc_inout"; } 1203 1204 // value initialization 1205 1206 inline void initialize( const sc_dt::sc_int<W>& value_ ) 1207 { 1208 inout_if_type* iface = this->get_interface(0); 1209 if( iface != 0 ) { 1210 iface->write( value_ ); 1211 } else { 1212 if( m_init_val_p == 0 ) { 1213 m_init_val_p = new sc_dt::int64; 1214 } 1215 *m_init_val_p = value_; 1216 } 1217 } 1218 1219 1220 // called by sc_trace 1221 void add_trace( sc_trace_file* tf_, const std::string& name_ ) const 1222 { 1223 if( tf_ != 0 ) { 1224 if( m_traces == 0 ) { 1225 m_traces = new sc_trace_params_vec; 1226 } 1227 m_traces->push_back( new sc_trace_params( tf_, name_ ) ); 1228 } 1229 } 1230 1231 1232 // concatenation methods 1233 1234 virtual inline int concat_length(bool* xz_present_p) const 1235 { return (*this)->read().concat_length( xz_present_p ); } 1236 virtual inline sc_dt::uint64 concat_get_uint64() const 1237 { return (*this)->read().concat_get_uint64(); } 1238 virtual 1239 inline bool concat_get_ctrl( sc_dt::sc_digit* dst_p, int low_i ) const 1240 { return (*this)->read().concat_get_ctrl(dst_p, low_i); } 1241 virtual 1242 inline bool concat_get_data( sc_dt::sc_digit* dst_p, int low_i ) const 1243 { return (*this)->read().concat_get_data(dst_p, low_i); } 1244 virtual inline void concat_set(sc_dt::int64 src, int low_i) 1245 { *this = src >> (( low_i < 64 ) ? low_i : 63); } 1246#if 0 // #### 1247 virtual inline void concat_set(const sc_dt::sc_lv_base& src, int low_i) 1248 { *this = src >> low_i; } 1249#endif // 0 #### 1250 virtual inline void concat_set(const sc_dt::sc_signed& src, int low_i) 1251 { *this = src >> low_i; } 1252 virtual inline void concat_set(const sc_dt::sc_unsigned& src, int low_i) 1253 { *this = src >> low_i; } 1254 virtual inline void concat_set(sc_dt::uint64 src, int low_i) 1255 { *this = ( low_i < 64 ) ? src >> low_i : (sc_dt::uint64)0; } 1256 1257 // assignment operators: 1258 1259 public: 1260 inline void operator = ( const this_type& new_val ) 1261 { (*this)->write( (sc_dt::int64)new_val ); } 1262 inline void operator = ( const char* new_val ) 1263 { (*this)->write( this_type(new_val) ); } 1264 inline void operator = ( sc_dt::uint64 new_val ) 1265 { (*this)->write(new_val); } 1266 inline void operator = ( sc_dt::int64 new_val ) 1267 { (*this)->write((sc_dt::uint64)new_val); } 1268 inline void operator = ( int new_val ) 1269 { (*this)->write((sc_dt::uint64)new_val); } 1270 inline void operator = ( long new_val ) 1271 { (*this)->write((sc_dt::uint64)new_val); } 1272 inline void operator = ( short new_val ) 1273 { (*this)->write((sc_dt::uint64)new_val); } 1274 inline void operator = ( unsigned int new_val ) 1275 { (*this)->write((sc_dt::uint64)new_val); } 1276 inline void operator = ( unsigned long new_val ) 1277 { (*this)->write((sc_dt::uint64)new_val); } 1278 inline void operator = ( unsigned short new_val ) 1279 { (*this)->write((sc_dt::uint64)new_val); } 1280 template<typename T> 1281 inline void operator = ( const sc_dt::sc_generic_base<T>& new_val ) 1282 { (*this)->write(new_val->to_uint64()); } 1283 inline void operator = ( const sc_dt::sc_signed& new_val ) 1284 { (*this)->write(new_val.to_uint64()); } 1285 inline void operator = ( const sc_dt::sc_unsigned& new_val ) 1286 { (*this)->write(new_val.to_uint64()); } 1287 inline void operator = ( const sc_dt::sc_bv_base& new_val ) 1288 { (*this)->write((sc_dt::sc_int<W>)new_val); } 1289 inline void operator = ( const sc_dt::sc_lv_base& new_val ) 1290 { (*this)->write((sc_dt::sc_int<W>)new_val); } 1291 1292 inline void write( const sc_in<sc_dt::sc_int<W> >& new_val ) 1293 { (*this)->write( (sc_dt::int64)new_val ); } 1294 1295 inline void write( const sc_inout<sc_dt::sc_int<W> >& new_val ) 1296 { (*this)->write( (sc_dt::int64)new_val); } 1297 1298 inline void write( const sc_dt::sc_int<W>& new_val ) 1299 { (*this)->write( (sc_dt::int64)new_val); } 1300 1301 protected: 1302 void remove_traces() const 1303 { 1304 if( m_traces != 0 ) { 1305 for( int i = m_traces->size() - 1; i >= 0; -- i ) { 1306 delete (*m_traces)[i]; 1307 } 1308 delete m_traces; 1309 m_traces = 0; 1310 } 1311 } 1312 1313 sc_dt::int64* m_init_val_p; 1314 mutable sc_trace_params_vec* m_traces; 1315 1316 1317 private: 1318 1319 // disabled 1320 sc_inout( const sc_inout<sc_dt::sc_int<W> >& ); 1321 1322#ifdef __GNUC__ 1323 // Needed to circumvent a problem in the g++-2.95.2 compiler: 1324 // This unused variable forces the compiler to instantiate 1325 // an object of T template so an implicit conversion from 1326 // read() to a C++ intrinsic data type will work. 1327 static data_type dummy; 1328#endif 1329 1330}; 1331 1332 1333 1334SC_TEMPLATE 1335inline std::ostream& operator << ( 1336 std::ostream& os, const sc_inout<sc_dt::sc_int<W> >& a ) 1337{ 1338 a.read().print( os ); 1339 return os; 1340} 1341 1342 1343//============================================================================== 1344// CLASS sc_out<sc_dt::sc_int<W> > 1345// 1346// This class implements an output port whose target acts like an 1347// sc_dt::sc_int<W> data value. This class is a derivation of sc_inout, since 1348// output ports are really no different from input/output ports. 1349//============================================================================== 1350SC_TEMPLATE 1351class sc_out<sc_dt::sc_int<W> > : public sc_inout<sc_dt::sc_int<W> > 1352{ 1353 public: 1354 1355 // typedefs 1356 1357 typedef sc_dt::sc_int<W> data_type; 1358 1359 typedef sc_out<data_type> this_type; 1360 typedef sc_inout<data_type> base_type; 1361 1362 typedef typename base_type::inout_if_type inout_if_type; 1363 typedef typename base_type::inout_port_type inout_port_type; 1364 1365 // constructors 1366 1367 sc_out() 1368 : base_type() 1369 {} 1370 1371 explicit sc_out( const char* name_ ) 1372 : base_type( name_ ) 1373 {} 1374 1375 explicit sc_out( inout_if_type& interface_ ) 1376 : base_type( interface_ ) 1377 {} 1378 1379 sc_out( const char* name_, inout_if_type& interface_ ) 1380 : base_type( name_, interface_ ) 1381 {} 1382 1383 explicit sc_out( inout_port_type& parent_ ) 1384 : base_type( parent_ ) 1385 {} 1386 1387 sc_out( const char* name_, inout_port_type& parent_ ) 1388 : base_type( name_, parent_ ) 1389 {} 1390 1391 sc_out( this_type& parent_ ) 1392 : base_type( parent_ ) 1393 {} 1394 1395 sc_out( const char* name_, this_type& parent_ ) 1396 : base_type( name_, parent_ ) 1397 {} 1398 1399 1400 // destructor (does nothing) 1401 1402 virtual inline ~sc_out() 1403 {} 1404 1405 1406 // assignment operators: 1407 1408 public: 1409 inline void operator = ( const this_type& new_val ) 1410 { (*this)->write( (sc_dt::int64)new_val ); } 1411 inline void operator = ( const char* new_val ) 1412 { (*this)->write( this_type(new_val) ); } 1413 inline void operator = ( sc_dt::uint64 new_val ) 1414 { (*this)->write(new_val); } 1415 inline void operator = ( sc_dt::int64 new_val ) 1416 { (*this)->write((sc_dt::uint64)new_val); } 1417 inline void operator = ( int new_val ) 1418 { (*this)->write((sc_dt::uint64)new_val); } 1419 inline void operator = ( long new_val ) 1420 { (*this)->write((sc_dt::uint64)new_val); } 1421 inline void operator = ( short new_val ) 1422 { (*this)->write((sc_dt::uint64)new_val); } 1423 inline void operator = ( unsigned int new_val ) 1424 { (*this)->write((sc_dt::uint64)new_val); } 1425 inline void operator = ( unsigned long new_val ) 1426 { (*this)->write((sc_dt::uint64)new_val); } 1427 inline void operator = ( unsigned short new_val ) 1428 { (*this)->write((sc_dt::uint64)new_val); } 1429 template<typename T> 1430 inline void operator = ( const sc_dt::sc_generic_base<T>& new_val ) 1431 { (*this)->write(new_val->to_uint64()); } 1432 inline void operator = ( const sc_dt::sc_signed& new_val ) 1433 { (*this)->write(new_val); } 1434 inline void operator = ( const sc_dt::sc_unsigned& new_val ) 1435 { (*this)->write(new_val); } 1436 inline void operator = ( const sc_dt::sc_bv_base& new_val ) 1437 { (*this)->write((sc_dt::sc_int<W>)new_val); } 1438 inline void operator = ( const sc_dt::sc_lv_base& new_val ) 1439 { (*this)->write((sc_dt::sc_int<W>)new_val); } 1440 1441 private: 1442 1443 // disabled 1444 sc_out( const this_type& ); 1445}; 1446 1447 1448 1449//------------------------------------------------------------------------------ 1450//"sc_int_sigref::initialize" 1451// 1452// This method initializes an object instance from the supplied arguments. 1453// if_p -> access to target of this selection. 1454// left = left-most bit in selection. 1455// right = right-most bit in selection. 1456//------------------------------------------------------------------------------ 1457inline 1458void sc_int_sigref::initialize(sc_int_part_if* if_p, int left, int right) 1459{ 1460 m_if_p = if_p; 1461 m_left = left; 1462 m_right = right; 1463 m_obj_p = if_p->part_read_target(); 1464} 1465 1466 1467//------------------------------------------------------------------------------ 1468//"sc_int_sigref::operator =" 1469// 1470// These operators assign a value to the bits associated with this object 1471// instance within this object instance's target signal. 1472//------------------------------------------------------------------------------ 1473inline void sc_int_sigref::operator = ( sc_dt::uint64 v ) 1474{ 1475 m_if_p->write_part( v, m_left, m_right ); 1476} 1477 1478inline void sc_int_sigref::operator = ( const char* /*v*/ ) 1479{ 1480} 1481 1482inline void sc_int_sigref:: operator = ( sc_dt::int64 v ) 1483{ 1484 *this = (sc_dt::uint64)v; 1485} 1486 1487inline void sc_int_sigref:: operator = ( int v ) 1488{ 1489 *this = (sc_dt::uint64)v; 1490} 1491 1492inline void sc_int_sigref:: operator = ( long v ) 1493{ 1494 *this = (sc_dt::uint64)v; 1495} 1496 1497inline void sc_int_sigref:: operator = ( unsigned int v ) 1498{ 1499 *this = (sc_dt::uint64)v; 1500} 1501 1502inline void sc_int_sigref:: operator = ( unsigned long v ) 1503{ 1504 *this = (sc_dt::uint64)v; 1505} 1506 1507void sc_int_sigref::operator = ( const sc_int_sigref& v ) 1508{ 1509 *this = (sc_dt::uint64)v; 1510} 1511 1512template<typename T> 1513inline void sc_int_sigref:: operator = ( const sc_dt::sc_generic_base<T>& v ) 1514{ 1515 *this = v->to_uint64(); 1516} 1517 1518inline void sc_int_sigref:: operator = ( const sc_dt::sc_signed& v ) 1519{ 1520 *this = v.to_uint64(); 1521} 1522 1523inline void sc_int_sigref:: operator = ( const sc_dt::sc_unsigned& v ) 1524{ 1525 *this = v.to_uint64(); 1526} 1527 1528#undef SC_TEMPLATE 1529#undef TTEST 1530} // namespace sc_core 1531#endif // !defined(SC_SIGNAL_INT_H) 1532 1533namespace sc_core { 1534 1535extern 1536void 1537sc_signal_invalid_writer( const char* name, 1538 const char* kind, 1539 const char* first_writer, 1540 const char* second_writer ); 1541 1542//------------------------------------------------------------------------------ 1543// POOL OF TEMPORARY INSTANCES OF sc_int_sigref 1544// 1545// This allows use to pass const references for part and bit selections 1546// on sc_signal_int object instances. 1547//------------------------------------------------------------------------------ 1548sc_vpool<sc_int_sigref> sc_int_sigref::m_pool(8); 1549 1550 1551//------------------------------------------------------------------------------ 1552//"sc_int_part_if::default methods" 1553// 1554// These versions just produce errors if they are not overloaded but used. 1555//------------------------------------------------------------------------------ 1556 1557sc_dt::sc_int_base* sc_int_part_if::part_read_target() 1558{ 1559 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" ); 1560 return 0; 1561} 1562sc_dt::uint64 sc_int_part_if::read_part( int /*left*/, int /*right*/ ) const 1563{ 1564 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" ); 1565 return 0; 1566} 1567sc_int_sigref& sc_int_part_if::select_part( int /*left*/, int /*right*/ ) 1568{ 1569 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" ); 1570 return *(sc_int_sigref*)0; 1571} 1572void sc_int_part_if::write_part( sc_dt::uint64 v, int /*left*/, int /*right*/ ) 1573{ 1574 SC_REPORT_ERROR( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, "int" ); 1575} 1576 1577 1578//------------------------------------------------------------------------------ 1579//"sc_int_sigref::concate_set" 1580// 1581// These methods assign this object instance's value from the supplied 1582// value starting at the supplied bit within that value. 1583// src = value to use to set this object instance's value. 1584// low_i = bit in src that is to be the low order bit of the value to set. 1585// #### OPTIMIZE 1586//------------------------------------------------------------------------------ 1587void sc_int_sigref::concat_set(sc_dt::int64 src, int low_i) 1588{ 1589 *this = (low_i < 64) ? src >> low_i : src >> 63; 1590} 1591 1592 1593void sc_int_sigref::concat_set(const sc_dt::sc_signed& src, int low_i) 1594{ 1595 if ( low_i < src.length() ) 1596 *this = src >> low_i; 1597 else 1598 *this = (src < 0) ? (sc_dt::uint64)-1 : 0; 1599} 1600 1601 1602void sc_int_sigref::concat_set(const sc_dt::sc_lv_base& src, int low_i) 1603{ 1604 if ( low_i < src.length() ) 1605 *this = (src >> low_i).to_uint64(); 1606 else 1607 *this = 0; 1608} 1609 1610 1611void sc_int_sigref::concat_set(const sc_dt::sc_unsigned& src, int low_i) 1612{ 1613 if ( low_i < src.length() ) 1614 *this = src >> low_i; 1615 else 1616 *this = 0; 1617} 1618 1619 1620void sc_int_sigref::concat_set(sc_dt::uint64 src, int low_i) 1621{ 1622 *this = (low_i < 64) ? src >> low_i : 0; 1623} 1624 1625} // namespace sc_core 1626