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