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