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