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_CLOCK_H
00028 #define SC_CLOCK_H
00029 
00030 
00031 #include "sysc/kernel/sc_module.h"
00032 #include "sysc/communication/sc_signal.h"
00033 #include "sysc/tracing/sc_trace.h"
00034 
00035 namespace sc_core {
00036 
00037 
00043 class sc_clock
00044   : public sc_signal<bool,SC_ONE_WRITER>
00045 {
00046   typedef sc_signal<bool,SC_ONE_WRITER> base_type;
00047 public:
00048 
00049     friend class sc_clock_posedge_callback;
00050     friend class sc_clock_negedge_callback;
00051 
00052     
00053 
00054     sc_clock();
00055 
00056     explicit sc_clock( const char* name_ );
00057 
00058     sc_clock( const char* name_,
00059               const sc_time& period_,
00060               double         duty_cycle_ = 0.5,
00061               const sc_time& start_time_ = SC_ZERO_TIME,
00062               bool           posedge_first_ = true );
00063 
00064     sc_clock( const char* name_,
00065               double         period_v_,
00066               sc_time_unit   period_tu_,
00067               double         duty_cycle_ = 0.5 );
00068 
00069     sc_clock( const char* name_,
00070               double         period_v_,
00071               sc_time_unit   period_tu_,
00072               double         duty_cycle_,
00073               double         start_time_v_,
00074               sc_time_unit   start_time_tu_,
00075               bool           posedge_first_ = true );
00076 
00077     
00078     sc_clock( const char* name_,
00079               double         period_,            
00080               double         duty_cycle_ = 0.5,
00081               double         start_time_ = 0.0,  
00082               bool           posedge_first_ = true );
00083 
00084     
00085     virtual ~sc_clock();
00086 
00087     virtual void register_port( sc_port_base&, const char* if_type );
00088     virtual void write( const bool& );
00089 
00090     
00091     const sc_time& period() const
00092     { return m_period; }
00093 
00094     
00095     double duty_cycle() const
00096     { return m_duty_cycle; }
00097 
00098 
00099     
00100 
00101     bool posedge_first() const
00102     { return m_posedge_first; }
00103 
00104     sc_time start_time() const
00105     { return m_start_time; }
00106 
00107     static const sc_time& time_stamp();
00108 
00109     virtual const char* kind() const
00110     { return "sc_clock"; }
00111 
00112 
00113 #if 0 // @@@@#### REMOVE
00114     
00115 
00116     sc_signal_in_if<bool>& signal()
00117         { return *this; }
00118 
00119     const sc_signal_in_if<bool>& signal() const
00120         { return *this; }
00121 
00122     static void start( const sc_time& duration )
00123         { sc_start( duration ); }
00124 
00125     static void start( double v, sc_time_unit tu )
00126         { sc_start( sc_time(v, tu) ); }
00127 
00128     static void start( double duration = -1 )
00129         { sc_start( duration ); }
00130 
00131     static void stop()
00132         { sc_stop(); }
00133 #endif
00134 
00135 protected:
00136 
00141     
00142     void before_end_of_elaboration();
00143 
00144     
00145     void posedge_action();
00146     void negedge_action();
00147 
00148 
00149     
00150     void report_error( const char* id, const char* add_msg = 0 ) const;
00151 
00152 
00153     void init( const sc_time&, double, const sc_time&, bool );
00154 
00155     bool is_clock() const { return true; }
00156 
00157 protected:
00158 
00159     sc_time  m_period;          
00160     double   m_duty_cycle;      
00161     sc_time  m_start_time;      
00162     bool     m_posedge_first;   
00163     sc_time  m_posedge_time;    
00164     sc_time  m_negedge_time;    
00165 
00166     sc_event m_next_posedge_event;
00167     sc_event m_next_negedge_event;
00168 
00169 private:
00170 
00171     
00172     sc_clock( const sc_clock& );
00173     sc_clock& operator = ( const sc_clock& );
00174 };
00175 
00176 
00177 
00178 
00179 
00180 
00181 inline
00182 void
00183 sc_clock::posedge_action()
00184 {
00185     
00186     chnl_scoped_lock lock( m_mutex );
00187 
00188     m_next_negedge_event.notify_internal( m_negedge_time );
00189     m_new_val = true;
00190     request_update();
00191     
00192 }
00193 
00194 inline
00195 void
00196 sc_clock::negedge_action()
00197 {
00198     
00199     chnl_scoped_lock lock( m_mutex );
00200 
00201     m_next_posedge_event.notify_internal( m_posedge_time );
00202     m_new_val = false;
00203     request_update();
00204     
00205 }
00206 
00207 
00208 
00209 
00210 class sc_clock_posedge_callback {
00211 public:
00212     sc_clock_posedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
00213     inline void operator () () { m_target_p->posedge_action(); }
00214   protected:
00215     sc_clock* m_target_p;
00216 };
00217 
00218 class sc_clock_negedge_callback {
00219   public:
00220     sc_clock_negedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
00221     inline void operator () () { m_target_p->negedge_action(); }
00222   protected:
00223     sc_clock* m_target_p;
00224 };
00225 
00226 
00227 } 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 #endif
00285 
00286