00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef SC_SIGNAL_H
00037 #define SC_SIGNAL_H
00038
00039
00040 #include "sysc/communication/sc_port.h"
00041 #include "sysc/communication/sc_prim_channel.h"
00042 #include "sysc/communication/sc_signal_ifs.h"
00043 #include "sysc/kernel/sc_event.h"
00044 #include "sysc/kernel/sc_process_b.h"
00045 #include "sysc/kernel/sc_simcontext.h"
00046 #include "sysc/datatypes/bit/sc_logic.h"
00047 #include "sysc/tracing/sc_trace.h"
00048 #include "sysc/utils/sc_string.h"
00049 #include <typeinfo>
00050
00051 namespace sc_core {
00052
00053
00054
00055 extern
00056 void
00057 sc_signal_invalid_writer( const char* name,
00058 const char* kind,
00059 const char* first_writer,
00060 const char* second_writer );
00061
00062
00063
00064
00065
00066
00067
00068
00069 template <class T>
00070 class sc_signal
00071 : public sc_signal_inout_if<T>,
00072 public sc_prim_channel
00073 {
00074 public:
00075
00076
00077
00078 sc_signal()
00079 : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
00080 m_output( 0 ), m_cur_val( T() ), m_new_val( T() ),
00081 m_delta( ~sc_dt::UINT64_ONE ), m_writer( 0 )
00082 {}
00083
00084 explicit sc_signal( const char* name_ )
00085 : sc_prim_channel( name_ ),
00086 m_output( 0 ), m_cur_val( T() ), m_new_val( T() ),
00087 m_delta( ~sc_dt::UINT64_ONE ), m_writer( 0 )
00088 {}
00089
00090
00091
00092
00093 virtual ~sc_signal()
00094 {}
00095
00096
00097
00098
00099 virtual void register_port( sc_port_base&, const char* );
00100
00101
00102
00103 virtual const sc_event& default_event() const
00104 { return m_value_changed_event; }
00105
00106
00107
00108 virtual const sc_event& value_changed_event() const
00109 { return m_value_changed_event; }
00110
00111
00112
00113 virtual const T& read() const
00114 { return m_cur_val; }
00115
00116
00117 virtual const T& get_data_ref() const
00118 { return m_cur_val; }
00119
00120
00121
00122 virtual bool event() const
00123 { return ( simcontext()->delta_count() == m_delta + 1 ); }
00124
00125
00126 virtual void write( const T& );
00127
00128
00129
00130
00131 operator const T& () const
00132 { return read(); }
00133
00134
00135 sc_signal<T>& operator = ( const T& a )
00136 { write( a ); return *this; }
00137
00138 sc_signal<T>& operator = ( const sc_signal<T>& a )
00139 { write( a.read() ); return *this; }
00140
00141
00142 const T& get_new_value() const
00143 { return m_new_val; }
00144
00145
00146 void trace( sc_trace_file* tf ) const
00147 #ifdef DEBUG_SYSTEMC
00148 { sc_trace( tf, get_data_ref(), name() ); }
00149 #else
00150 {}
00151 #endif
00152
00153
00154 virtual void print( ::std::ostream& = ::std::cout ) const;
00155 virtual void dump( ::std::ostream& = ::std::cout ) const;
00156
00157 virtual const char* kind() const
00158 { return "sc_signal"; }
00159
00160 protected:
00161
00162 virtual void update();
00163
00164 void check_writer();
00165
00166 protected:
00167
00168 sc_port_base* m_output;
00169
00170 T m_cur_val;
00171 T m_new_val;
00172
00173 sc_event m_value_changed_event;
00174
00175 sc_dt::uint64 m_delta;
00176
00177 sc_process_b* m_writer;
00178
00179 private:
00180
00181
00182 sc_signal( const sc_signal<T>& );
00183 };
00184
00185
00186
00187
00188
00189 template <class T>
00190 inline
00191 void
00192 sc_signal<T>::register_port( sc_port_base& port_, const char* if_typename_ )
00193 {
00194 #ifdef DEBUG_SYSTEMC
00195 std::string nm( if_typename_ );
00196 if( nm == typeid( sc_signal_inout_if<T> ).name() ) {
00197
00198 if( m_output != 0 ) {
00199 sc_signal_invalid_writer( name(), kind(),
00200 m_output->name(), port_.name() );
00201 }
00202 m_output = &port_;
00203 }
00204 #endif
00205 }
00206
00207
00208
00209
00210 template <class T>
00211 inline
00212 void
00213 sc_signal<T>::write( const T& value_ )
00214 {
00215 #ifdef DEBUG_SYSTEMC
00216 check_writer();
00217 #endif
00218 m_new_val = value_;
00219 if( !( m_new_val == m_cur_val ) ) {
00220 request_update();
00221 }
00222 }
00223
00224
00225 template <class T>
00226 inline
00227 void
00228 sc_signal<T>::print( ::std::ostream& os ) const
00229 {
00230 os << m_cur_val;
00231 }
00232
00233 template <class T>
00234 inline
00235 void
00236 sc_signal<T>::dump( ::std::ostream& os ) const
00237 {
00238 os << " name = " << name() << ::std::endl;
00239 os << " value = " << m_cur_val << ::std::endl;
00240 os << "new value = " << m_new_val << ::std::endl;
00241 }
00242
00243
00244 template <class T>
00245 inline
00246 void
00247 sc_signal<T>::update()
00248 {
00249 if( !( m_new_val == m_cur_val ) ) {
00250 m_cur_val = m_new_val;
00251 m_value_changed_event.notify_delayed();
00252 m_delta = simcontext()->delta_count();
00253 }
00254 }
00255
00256
00257 template <class T>
00258 inline
00259 void
00260 sc_signal<T>::check_writer()
00261 {
00262 sc_process_b* writer = sc_get_curr_process_handle();
00263 if( m_writer == 0 ) {
00264 m_writer = writer;
00265 } else if( m_writer != writer ) {
00266 sc_signal_invalid_writer( name(), kind(),
00267 m_writer->name(), writer->name() );
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278 template <>
00279 class sc_signal<bool>
00280 : public sc_signal_inout_if<bool>,
00281 public sc_prim_channel
00282 {
00283 public:
00284
00285
00286
00287 sc_signal()
00288 : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
00289 m_output( 0 ),
00290 m_cur_val( false ),
00291 m_new_val( false ),
00292 m_delta( ~sc_dt::UINT64_ONE ),
00293 m_writer( 0 )
00294 {}
00295
00296 explicit sc_signal( const char* name_ )
00297 : sc_prim_channel( name_ ),
00298 m_output( 0 ),
00299 m_cur_val( false ),
00300 m_new_val( false ),
00301 m_delta( ~sc_dt::UINT64_ONE ),
00302 m_writer( 0 )
00303 {}
00304
00305
00306
00307
00308 virtual ~sc_signal()
00309 {}
00310
00311
00312
00313
00314 virtual void register_port( sc_port_base&, const char* );
00315
00316
00317
00318 virtual const sc_event& default_event() const
00319 { return m_value_changed_event; }
00320
00321
00322
00323 virtual const sc_event& value_changed_event() const
00324 { return m_value_changed_event; }
00325
00326
00327 virtual const sc_event& posedge_event() const
00328 { return m_posedge_event; }
00329
00330
00331 virtual const sc_event& negedge_event() const
00332 { return m_negedge_event; }
00333
00334
00335
00336 virtual const bool& read() const
00337 { return m_cur_val; }
00338
00339
00340 virtual const bool& get_data_ref() const
00341 { return m_cur_val; }
00342
00343
00344
00345 virtual bool event() const
00346 { return ( simcontext()->delta_count() == m_delta + 1 ); }
00347
00348
00349 virtual bool posedge() const
00350 { return ( event() && m_cur_val ); }
00351
00352
00353 virtual bool negedge() const
00354 { return ( event() && ! m_cur_val ); }
00355
00356
00357
00358 virtual void write( const bool& );
00359
00360
00361
00362 virtual const sc_signal_bool_deval& delayed() const;
00363
00364
00365
00366 operator const bool& () const
00367 { return read(); }
00368
00369
00370 sc_signal<bool>& operator = ( const bool& a )
00371 { write( a ); return *this; }
00372
00373 sc_signal<bool>& operator = ( const sc_signal<bool>& a )
00374 { write( a.read() ); return *this; }
00375
00376
00377 const bool& get_new_value() const
00378 { return m_new_val; }
00379
00380
00381 void trace( sc_trace_file* tf ) const
00382 #ifdef DEBUG_SYSTEMC
00383 { sc_trace( tf, get_data_ref(), name() ); }
00384 #else
00385 {}
00386 #endif
00387
00388
00389 virtual void print( ::std::ostream& = ::std::cout ) const;
00390 virtual void dump( ::std::ostream& = ::std::cout ) const;
00391
00392 virtual const char* kind() const
00393 { return "sc_signal"; }
00394
00395 protected:
00396
00397 virtual void update();
00398
00399 void check_writer();
00400
00401 virtual bool is_clock() const { return false; }
00402
00403 protected:
00404
00405 sc_port_base* m_output;
00406
00407 bool m_cur_val;
00408 bool m_new_val;
00409
00410 sc_event m_value_changed_event;
00411 sc_event m_posedge_event;
00412 sc_event m_negedge_event;
00413
00414 sc_dt::uint64 m_delta;
00415
00416 sc_process_b* m_writer;
00417
00418 private:
00419
00420
00421 sc_signal( const sc_signal<bool>& );
00422 };
00423
00424
00425
00426
00427 inline
00428 void
00429 sc_signal<bool>::register_port( sc_port_base& port_, const char* if_typename_ )
00430 {
00431 #ifdef DEBUG_SYSTEMC
00432 std::string nm( if_typename_ );
00433 if( nm == typeid( sc_signal_inout_if<bool> ).name() ) {
00434
00435 if( m_output != 0 ) {
00436 sc_signal_invalid_writer( name(), kind(),
00437 m_output->name(), port_.name() );
00438 }
00439 m_output = &port_;
00440 }
00441 #endif
00442 }
00443
00444
00445
00446
00447 inline
00448 void
00449 sc_signal<bool>::write( const bool& value_ )
00450 {
00451 #ifdef DEBUG_SYSTEMC
00452 check_writer();
00453 #endif
00454 m_new_val = value_;
00455 if( !( m_new_val == m_cur_val ) ) {
00456 request_update();
00457 }
00458 }
00459
00460
00461
00462
00463 inline
00464 const sc_signal_bool_deval&
00465 sc_signal<bool>::delayed() const
00466 {
00467 const sc_signal_in_if<bool>* iface = this;
00468 return RCAST<const sc_signal_bool_deval&>( *iface );
00469 }
00470
00471
00472 inline
00473 void
00474 sc_signal<bool>::print( ::std::ostream& os ) const
00475 {
00476 os << m_cur_val;
00477 }
00478
00479 inline
00480 void
00481 sc_signal<bool>::dump( ::std::ostream& os ) const
00482 {
00483 os << " name = " << name() << ::std::endl;
00484 os << " value = " << m_cur_val << ::std::endl;
00485 os << "new value = " << m_new_val << ::std::endl;
00486 }
00487
00488
00489 inline
00490 void
00491 sc_signal<bool>::update()
00492 {
00493 if( !( m_new_val == m_cur_val ) ) {
00494 m_cur_val = m_new_val;
00495 m_value_changed_event.notify_delayed();
00496 if( m_cur_val ) {
00497 m_posedge_event.notify_delayed();
00498 } else {
00499 m_negedge_event.notify_delayed();
00500 }
00501 m_delta = simcontext()->delta_count();
00502 }
00503 }
00504
00505
00506 inline
00507 void
00508 sc_signal<bool>::check_writer()
00509 {
00510 if (is_clock()) return;
00511 sc_process_b* writer = sc_get_curr_process_handle();
00512 if( m_writer == 0 ) {
00513 m_writer = writer;
00514 } else if( m_writer != writer ) {
00515 sc_signal_invalid_writer( name(), kind(),
00516 m_writer->name(), writer->name() );
00517 }
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527 template <>
00528 class sc_signal<sc_dt::sc_logic>
00529 : public sc_signal_inout_if<sc_dt::sc_logic>,
00530 public sc_prim_channel
00531 {
00532 public:
00533
00534
00535
00536 sc_signal()
00537 : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
00538 m_output( 0 ),
00539 m_cur_val(),
00540 m_new_val(),
00541 m_delta( ~sc_dt::UINT64_ONE ),
00542 m_writer( 0 )
00543 {}
00544
00545 explicit sc_signal( const char* name_ )
00546 : sc_prim_channel( name_ ),
00547 m_output( 0 ),
00548 m_cur_val(),
00549 m_new_val(),
00550 m_delta( ~sc_dt::UINT64_ONE ),
00551 m_writer( 0 )
00552 {}
00553
00554
00555
00556
00557 virtual ~sc_signal()
00558 {}
00559
00560
00561
00562
00563 virtual void register_port( sc_port_base&, const char* );
00564
00565
00566
00567 virtual const sc_event& default_event() const
00568 { return m_value_changed_event; }
00569
00570
00571
00572 virtual const sc_event& value_changed_event() const
00573 { return m_value_changed_event; }
00574
00575
00576 virtual const sc_event& posedge_event() const
00577 { return m_posedge_event; }
00578
00579
00580 virtual const sc_event& negedge_event() const
00581 { return m_negedge_event; }
00582
00583
00584
00585 virtual const sc_dt::sc_logic& read() const
00586 { return m_cur_val; }
00587
00588
00589 virtual const sc_dt::sc_logic& get_data_ref() const
00590 { return m_cur_val; }
00591
00592
00593
00594 virtual bool event() const
00595 { return ( simcontext()->delta_count() == m_delta + 1 ); }
00596
00597
00598 virtual bool posedge() const
00599 { return ( event() && m_cur_val == sc_dt::SC_LOGIC_1 ); }
00600
00601
00602 virtual bool negedge() const
00603 { return ( event() && m_cur_val == sc_dt::SC_LOGIC_0 ); }
00604
00605
00606
00607 virtual void write( const sc_dt::sc_logic& );
00608
00609
00610
00611 virtual const sc_signal_logic_deval& delayed() const;
00612
00613
00614
00615
00616 operator const sc_dt::sc_logic& () const
00617 { return read(); }
00618
00619
00620 sc_signal<sc_dt::sc_logic>& operator = ( const sc_dt::sc_logic& a )
00621 { write( a ); return *this; }
00622
00623 sc_signal<sc_dt::sc_logic>& operator = (const sc_signal<sc_dt::sc_logic>& a)
00624 { write( a.read() ); return *this; }
00625
00626
00627 const sc_dt::sc_logic& get_new_value() const
00628 { return m_new_val; }
00629
00630
00631 void trace( sc_trace_file* tf ) const
00632 #ifdef DEBUG_SYSTEMC
00633 { sc_trace( tf, get_data_ref(), name() ); }
00634 #else
00635 {}
00636 #endif
00637
00638
00639 virtual void print( ::std::ostream& = ::std::cout ) const;
00640 virtual void dump( ::std::ostream& = ::std::cout ) const;
00641
00642 virtual const char* kind() const
00643 { return "sc_signal"; }
00644
00645 protected:
00646
00647 virtual void update();
00648
00649 void check_writer();
00650
00651 protected:
00652
00653 sc_port_base* m_output;
00654
00655 sc_dt::sc_logic m_cur_val;
00656 sc_dt::sc_logic m_new_val;
00657
00658 sc_event m_value_changed_event;
00659 sc_event m_posedge_event;
00660 sc_event m_negedge_event;
00661
00662 sc_dt::uint64 m_delta;
00663
00664 sc_process_b* m_writer;
00665
00666 private:
00667
00668
00669 sc_signal( const sc_signal<sc_dt::sc_logic>& );
00670 };
00671
00672
00673
00674
00675 inline
00676 void
00677 sc_signal<sc_dt::sc_logic>::register_port( sc_port_base& port_,
00678 const char* if_typename_ )
00679 {
00680 #ifdef DEBUG_SYSTEMC
00681 std::string nm( if_typename_ );
00682 if( nm == typeid( sc_signal_inout_if<sc_dt::sc_logic> ).name() ) {
00683
00684 if( m_output != 0 ) {
00685 sc_signal_invalid_writer( name(), kind(),
00686 m_output->name(), port_.name() );
00687 }
00688 m_output = &port_;
00689 }
00690 #endif
00691 }
00692
00693
00694
00695
00696 inline
00697 void
00698 sc_signal<sc_dt::sc_logic>::write( const sc_dt::sc_logic& value_ )
00699 {
00700 #ifdef DEBUG_SYSTEMC
00701 check_writer();
00702 #endif
00703 m_new_val = value_;
00704 if( !( m_new_val == m_cur_val ) ) {
00705 request_update();
00706 }
00707 }
00708
00709
00710
00711
00712 inline
00713 const sc_signal_logic_deval&
00714 sc_signal<sc_dt::sc_logic>::delayed() const
00715 {
00716 const sc_signal_in_if<sc_dt::sc_logic>* iface = this;
00717 return RCAST<const sc_signal_logic_deval&>( *iface );
00718 }
00719
00720
00721 inline
00722 void
00723 sc_signal<sc_dt::sc_logic>::print( ::std::ostream& os ) const
00724 {
00725 os << m_cur_val;
00726 }
00727
00728 inline
00729 void
00730 sc_signal<sc_dt::sc_logic>::dump( ::std::ostream& os ) const
00731 {
00732 os << " name = " << name() << ::std::endl;
00733 os << " value = " << m_cur_val << ::std::endl;
00734 os << "new value = " << m_new_val << ::std::endl;
00735 }
00736
00737
00738 inline
00739 void
00740 sc_signal<sc_dt::sc_logic>::update()
00741 {
00742 if( !( m_new_val == m_cur_val ) ) {
00743 m_cur_val = m_new_val;
00744 m_value_changed_event.notify_delayed();
00745 if( m_cur_val == sc_dt::SC_LOGIC_1 ) {
00746 m_posedge_event.notify_delayed();
00747 } else if( m_cur_val == sc_dt::SC_LOGIC_0 ) {
00748 m_negedge_event.notify_delayed();
00749 }
00750 m_delta = simcontext()->delta_count();
00751 }
00752 }
00753
00754
00755
00756 inline
00757 void
00758 sc_signal<sc_dt::sc_logic>::check_writer()
00759 {
00760 sc_process_b* writer = sc_get_curr_process_handle();
00761 if( m_writer == 0 ) {
00762 m_writer = writer;
00763 } else if( m_writer != writer ) {
00764 sc_signal_invalid_writer( name(), kind(),
00765 m_writer->name(), writer->name() );
00766 }
00767 }
00768
00769
00770
00771
00772 template <class T>
00773 inline
00774 ::std::ostream&
00775 operator << ( ::std::ostream& os, const sc_signal<T>& a )
00776 {
00777 return ( os << a.read() );
00778 }
00779
00780 }
00781
00782 #endif
00783
00784