Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

sc_clock.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2004 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.3 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_clock.cpp -- The clock channel.
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00032                                Andy Goodrich, Forte Design Systems,
00033                                3 October, 2003
00034   Description of Modification: sc_clock inherits from sc_signal<bool> only
00035                                instead of sc_signal_in_if<bool> and sc_module.
00036                                The 2 methods posedge_action() and 
00037                                negedge_action() are created using sc_spawn(). 
00038                                boost::bind() is not required, instead a local
00039                                bind function can be used since the signatures
00040                                of the spawned functions are statically known.
00041 
00042       Name, Affiliation, Date:
00043   Description of Modification:
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 // using sc_dp::sc_spawn_options;
00053 
00054 
00055 // ----------------------------------------------------------------------------
00056 //  CLASS : sc_clock
00057 //
00058 //  The clock channel.
00059 // ----------------------------------------------------------------------------
00060 
00061 // constructors
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   // posedge first
00099   m_next_posedge_event.notify_delayed( m_start_time );
00100     } else {
00101   // negedge first
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     // posedge first
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   // posedge first
00137   m_next_posedge_event.notify_delayed( m_start_time );
00138     } else {
00139   // negedge first
00140   m_next_negedge_event.notify_delayed( m_start_time );
00141     }
00142 }
00143 
00144 // for backward compatibility with 1.0
00145 sc_clock::sc_clock( const char* name_,
00146         double         period_,      // in default time units
00147         double         duty_cycle_,
00148         double         start_time_,  // in default time units
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   // posedge first
00159   m_next_posedge_event.notify_delayed( m_start_time );
00160     } else {
00161   // negedge first
00162   m_next_negedge_event.notify_delayed( m_start_time );
00163     }
00164 }
00165 
00166 
00167 //------------------------------------------------------------------------------
00168 //"sc_clock::before_end_of_elaboration"
00169 //
00170 // This callback is used to spawn the edge processes for this object instance.
00171 // The processes are created here rather than the constructor for the object
00172 // so that the processes are registered with the global simcontext rather
00173 // than the scope of the clock's parent.
00174 //------------------------------------------------------------------------------
00175 void sc_clock::before_end_of_elaboration()
00176 {
00177     sc_spawn_options posedge_options; // Options for posedge process.
00178     sc_spawn_options negedge_options; // Options for negedge process.
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 // destructor (does nothing)
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 // interface methods
00207 
00208 // get the current time
00209 
00210 const sc_time&
00211 sc_clock::time_stamp()
00212 {
00213     return sc_time_stamp();
00214 }
00215 
00216 
00217 // error reporting
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 // Taf!

Generated on Fri Jan 14 08:29:00 2005 for SystemC2.1beta11(excludingMSLib)(IncludingSCV)\nProvidedby:www.openverificationfoundation.org by doxygen1.2.18