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