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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "systemc/communication/sc_clock.h"
00049 #include "systemc/communication/sc_communication_ids.h"
00050 #include "systemc/kernel/sc_simcontext.h"
00051 #include "systemc/kernel/sc_process_base.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 sc_clock::sc_clock()
00064 : sc_signal<bool>( sc_gen_unique_name( "clock" ) )
00065 {
00066 init( sc_time( 1.0, true ),
00067 0.5,
00068 SC_ZERO_TIME,
00069 true );
00070
00071 m_next_posedge_event.notify_delayed( m_start_time );
00072 }
00073
00074 sc_clock::sc_clock( const char* name_ )
00075 : sc_signal<bool>( name_ )
00076 {
00077 init( sc_time( 1.0, true ),
00078 0.5,
00079 SC_ZERO_TIME,
00080 true );
00081
00082 m_next_posedge_event.notify_delayed( m_start_time );
00083 }
00084
00085 sc_clock::sc_clock( const char* name_,
00086 const sc_time& period_,
00087 double duty_cycle_,
00088 const sc_time& start_time_,
00089 bool posedge_first_ )
00090 : sc_signal<bool>( name_ )
00091 {
00092 init( period_,
00093 duty_cycle_,
00094 start_time_,
00095 posedge_first_ );
00096
00097 if( posedge_first_ ) {
00098
00099 m_next_posedge_event.notify_delayed( m_start_time );
00100 } else {
00101
00102 m_next_negedge_event.notify_delayed( m_start_time );
00103 }
00104 }
00105
00106 sc_clock::sc_clock( const char* name_,
00107 double period_v_,
00108 sc_time_unit period_tu_,
00109 double duty_cycle_ )
00110 : sc_signal<bool>( name_ )
00111 {
00112 init( sc_time( period_v_, period_tu_, simcontext() ),
00113 duty_cycle_,
00114 SC_ZERO_TIME,
00115 true );
00116
00117
00118 m_next_posedge_event.notify_delayed( m_start_time );
00119 }
00120
00121 sc_clock::sc_clock( const char* name_,
00122 double period_v_,
00123 sc_time_unit period_tu_,
00124 double duty_cycle_,
00125 double start_time_v_,
00126 sc_time_unit start_time_tu_,
00127 bool posedge_first_ )
00128 : sc_signal<bool>( name_ )
00129 {
00130 init( sc_time( period_v_, period_tu_, simcontext() ),
00131 duty_cycle_,
00132 sc_time( start_time_v_, start_time_tu_, simcontext() ),
00133 posedge_first_ );
00134
00135 if( posedge_first_ ) {
00136
00137 m_next_posedge_event.notify_delayed( m_start_time );
00138 } else {
00139
00140 m_next_negedge_event.notify_delayed( m_start_time );
00141 }
00142 }
00143
00144
00145 sc_clock::sc_clock( const char* name_,
00146 double period_,
00147 double duty_cycle_,
00148 double start_time_,
00149 bool posedge_first_ )
00150 : sc_signal<bool>( name_ )
00151 {
00152 init( sc_time( period_, true ),
00153 duty_cycle_,
00154 sc_time( start_time_, true ),
00155 posedge_first_ );
00156
00157 if( posedge_first_ ) {
00158
00159 m_next_posedge_event.notify_delayed( m_start_time );
00160 } else {
00161
00162 m_next_negedge_event.notify_delayed( m_start_time );
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 void sc_clock::before_end_of_elaboration()
00176 {
00177 sc_spawn_options posedge_options;
00178 sc_spawn_options negedge_options;
00179
00180 posedge_options.spawn_method();
00181 posedge_options.dont_initialize();
00182 posedge_options.set_sensitivity(&m_next_posedge_event);
00183 sc_spawn(sc_clock_posedge_callback(this),
00184 sc_gen_unique_name( sc_string(basename()) + "_posedge_action"),
00185 &posedge_options);
00186
00187 negedge_options.spawn_method();
00188 negedge_options.dont_initialize();
00189 negedge_options.set_sensitivity(&m_next_negedge_event);
00190 sc_spawn( sc_clock_negedge_callback(this),
00191 sc_gen_unique_name( sc_string(basename()) + "_negedge_action" ),
00192 &negedge_options );
00193 }
00194
00195
00196
00197 sc_clock::~sc_clock()
00198 {}
00199
00200 void
00201 sc_clock::write( const bool& value)
00202 {
00203 SC_REPORT_ERROR(SC_ID_ATTEMPT_TO_WRITE_TO_CLOCK_, "");
00204 }
00205
00206
00207
00208
00209
00210 const sc_time&
00211 sc_clock::time_stamp()
00212 {
00213 return sc_time_stamp();
00214 }
00215
00216
00217
00218
00219 void
00220 sc_clock::report_error( const char* id, const char* add_msg ) const
00221 {
00222 char msg[BUFSIZ];
00223 if( add_msg != 0 ) {
00224 sprintf( msg, "%s: clock '%s'", add_msg, name() );
00225 } else {
00226 sprintf( msg, "clock '%s'", name() );
00227 }
00228 SC_REPORT_ERROR( id, msg );
00229 }
00230
00231
00232 void
00233 sc_clock::init( const sc_time& period_,
00234 double duty_cycle_,
00235 const sc_time& start_time_,
00236 bool posedge_first_ )
00237 {
00238 if( period_ == SC_ZERO_TIME ) {
00239 report_error( SC_ID_CLOCK_PERIOD_ZERO_,
00240 "increase the period" );
00241 }
00242 m_period = period_;
00243
00244 if( duty_cycle_ <= 0.0 || duty_cycle_ >= 1.0 ) {
00245 m_duty_cycle = 0.5;
00246 } else {
00247 m_duty_cycle = duty_cycle_;
00248 }
00249
00250 m_negedge_time = m_period * m_duty_cycle;
00251 m_posedge_time = m_period - m_negedge_time;
00252
00253 if( m_negedge_time == SC_ZERO_TIME ) {
00254 report_error( SC_ID_CLOCK_HIGH_TIME_ZERO_,
00255 "increase the period or increase the duty cycle" );
00256 }
00257 if( m_posedge_time == SC_ZERO_TIME ) {
00258 report_error( SC_ID_CLOCK_LOW_TIME_ZERO_,
00259 "increase the period or decrease the duty cycle" );
00260 }
00261
00262 if( posedge_first_ ) {
00263 this->m_cur_val = false;
00264 this->m_new_val = false;
00265 } else {
00266 this->m_cur_val = true;
00267 this->m_new_val = true;
00268 }
00269
00270 m_start_time = start_time_;
00271
00272 }
00273
00274