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

sc_module.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_module.cpp -- Base class of all sequential and combinational processes.
00021 
00022   Original Author: Stan Y. Liao, Synopsys, Inc.
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: Ali Dasdan, Synopsys, Inc.
00032   Description of Modification: - Implementation of operator() and operator,
00033                                  positional connection method.
00034                                - Implementation of error checking in
00035                                  operator<<'s.
00036                                - Implementation of the function test_module_prm.
00037                                - Implementation of set_stack_size().
00038 
00039       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
00040   Description of Modification: Inherit from sc_process_host
00041 
00042       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00043                                25 August, 2003
00044   Description of Modification: dont_initialize() uses 
00045                                sc_get_last_created_process_handle() instead of
00046                                sc_get_curr_process_handle()
00047 
00048  *****************************************************************************/
00049 
00050 
00051 #include <assert.h>
00052 #include <math.h>
00053 #include <stdio.h>
00054 
00055 #include "systemc/kernel/sc_event.h"
00056 #include "systemc/kernel/sc_kernel_ids.h"
00057 #include "systemc/kernel/sc_macros_int.h"
00058 #include "systemc/kernel/sc_module.h"
00059 #include "systemc/kernel/sc_module_registry.h"
00060 #include "systemc/kernel/sc_name_gen.h"
00061 #include "systemc/kernel/sc_object_manager.h"
00062 #include "systemc/kernel/sc_process.h"
00063 #include "systemc/kernel/sc_process_int.h"
00064 #include "systemc/kernel/sc_simcontext.h"
00065 #include "systemc/kernel/sc_simcontext_int.h"
00066 #include "systemc/communication/sc_communication_ids.h"
00067 #include "systemc/communication/sc_interface.h"
00068 #include "systemc/communication/sc_port.h"
00069 #include "systemc/utils/sc_iostream.h"
00070 
00071 // ----------------------------------------------------------------------------
00072 //  CLASS : sc_module_dynalloc_list
00073 //
00074 //  Garbage collection for modules dynamically allocated with SC_NEW.
00075 // ----------------------------------------------------------------------------
00076 
00077 class sc_module_dynalloc_list
00078 {
00079 public:
00080 
00081     sc_module_dynalloc_list()
00082         {}
00083 
00084     ~sc_module_dynalloc_list();
00085 
00086     void add( sc_module* p )
00087         { m_list.push_back( p ); }
00088 
00089 private:
00090 
00091     sc_plist<sc_module*> m_list;
00092 };
00093 
00094 
00095 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00096 
00097 sc_module_dynalloc_list::~sc_module_dynalloc_list()
00098 {
00099     sc_plist<sc_module*>::iterator it( m_list );
00100     while( ! it.empty() ) {
00101         delete *it;
00102         it ++;
00103     }
00104 }
00105 
00106 
00107 // ----------------------------------------------------------------------------
00108 
00109 sc_module*
00110 sc_module_dynalloc( sc_module* module_ )
00111 {
00112     static sc_module_dynalloc_list dynalloc_list;
00113     dynalloc_list.add( module_ );
00114     return module_;
00115 }
00116 
00117 
00118 // ----------------------------------------------------------------------------
00119 //  STRUCT : sc_bind_proxy
00120 //
00121 //  Struct for temporarily storing a pointer to an interface or port.
00122 //  Used for positional binding.
00123 // ----------------------------------------------------------------------------
00124     
00125 sc_bind_proxy::sc_bind_proxy()
00126 : iface( 0 ),
00127   port( 0 )
00128 {}
00129 
00130 sc_bind_proxy::sc_bind_proxy( sc_interface& iface_ )
00131 : iface( &iface_ ),
00132   port( 0 )
00133 {}
00134 
00135 sc_bind_proxy::sc_bind_proxy( sc_port_base& port_ )
00136 : iface( 0 ),
00137   port( &port_ )
00138 {}
00139 
00140 
00141 const sc_bind_proxy SC_BIND_PROXY_NIL;
00142 
00143 
00144 // ----------------------------------------------------------------------------
00145 //  CLASS : sc_module
00146 //
00147 //  Base class for all structural entities.
00148 // ----------------------------------------------------------------------------
00149 
00150 void
00151 sc_module::sc_module_init()
00152 {
00153     simcontext()->hierarchy_push( this );
00154     m_end_module_called = false;
00155     m_port_vec = new sc_pvector<sc_port_base*>( 16 );
00156     m_port_index = 0;
00157     m_name_gen = new sc_name_gen;
00158     simcontext()->get_module_registry()->insert( *this );
00159 }
00160 
00161 sc_module::sc_module( const char* nm )
00162 : sc_process_host(nm),
00163   sensitive(this),
00164   sensitive_pos(this),
00165   sensitive_neg(this)
00166 {
00167     sc_module_init();
00168 }
00169 
00170 /*
00171  *  This form of the constructor assumes that the user has
00172  *  used an sc_module_name parameter for his/her constructor.
00173  *  That parameter object has been pushed onto the stack,
00174  *  and can be looked up by calling the 
00175  *  top_of_module_name_stack() function of the object manager.
00176  *  This technique has two advantages:
00177  *
00178  *  1) The user no longer has to write sc_module(name) in the
00179  *     constructor initializer.
00180  *  2) The user no longer has to call end_module() at the end
00181  *     of the constructor -- a common negligence.
00182  *
00183  *  But it is important to note that sc_module_name may be used
00184  *  in the user's constructor's parameter. If it is used anywhere
00185  *  else, unexpected things will happen. The error-checking
00186  *  mechanism builtin here cannot hope to catch all misuses.
00187  *
00188  */
00189 
00190 sc_module::sc_module()
00191 : sc_process_host(::sc_get_curr_simcontext()
00192                   ->get_object_manager()
00193                   ->top_of_module_name_stack()
00194                   ->operator const char*()),
00195   sensitive(this),
00196   sensitive_pos(this),
00197   sensitive_neg(this)
00198 {
00199     /* When this form is used, we better have a fresh sc_module_name
00200        on the top of the stack */
00201     sc_module_name* mod_name = 
00202         simcontext()->get_object_manager()->top_of_module_name_stack();
00203     if (0 == mod_name || 0 != mod_name->m_module)
00204         SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
00205     mod_name->m_module = this;
00206     sc_module_init();
00207 }
00208 
00209 sc_module::sc_module( const sc_module_name& )
00210 : sc_process_host(::sc_get_curr_simcontext()
00211                   ->get_object_manager()
00212                   ->top_of_module_name_stack()
00213                   ->operator const char*()),
00214   sensitive(this),
00215   sensitive_pos(this),
00216   sensitive_neg(this)
00217 {
00218     /* For those used to the old style of passing a name to sc_module,
00219        this constructor will reduce the chance of making a mistake */
00220 
00221     /* When this form is used, we better have a fresh sc_module_name
00222        on the top of the stack */
00223     sc_module_name* mod_name = 
00224         simcontext()->get_object_manager()->top_of_module_name_stack();
00225     if (0 == mod_name || 0 != mod_name->m_module)
00226       SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
00227     mod_name->m_module = this;
00228     sc_module_init();
00229 }
00230 
00231 sc_module::sc_module( const sc_string& s )
00232 : sc_process_host( s.c_str() ),
00233   sensitive(this),
00234   sensitive_pos(this),
00235   sensitive_neg(this)
00236 {
00237     sc_module_init();
00238 }
00239 
00240 sc_module::~sc_module()
00241 {
00242     delete m_port_vec;
00243     delete m_name_gen;
00244     simcontext()->get_module_registry()->remove( *this );
00245 }
00246 
00247 
00248 const sc_pvector<sc_object*>&
00249 sc_module::get_child_objects() const
00250 {
00251     return m_child_objects;
00252 }
00253 
00254 void
00255 sc_module::add_child_object( sc_object* object_ )
00256 {
00257     // no check if object_ is already in the set
00258     m_child_objects.push_back( object_ );
00259 }
00260 
00261 void
00262 sc_module::remove_child_object( sc_object* object_ )
00263 {
00264     int size = m_child_objects.size();
00265     for( int i = 0; i < size; ++ i ) {
00266   if( object_ == m_child_objects[i] ) {
00267       m_child_objects[i] = m_child_objects[size - 1];
00268       m_child_objects.decr_count();
00269       return;
00270   }
00271     }
00272     // no check if object_ is really in the set
00273 }
00274 
00275 
00276 void
00277 sc_module::end_module()
00278 {
00279     if( ! m_end_module_called ) {
00280   /* TBD: Can check here to alert the user that end_module
00281                 was not called for a previous module. */
00282   (void) simcontext()->hierarchy_pop();
00283   simcontext()->reset_curr_proc(); 
00284   sensitive.reset();
00285   sensitive_pos.reset();
00286   sensitive_neg.reset();
00287   m_end_module_called = true;
00288     }
00289 }
00290 
00291 
00292 // to prevent initialization for SC_METHODs and SC_THREADs
00293 
00294 void
00295 sc_module::dont_initialize()
00296 {
00297     sc_process_b* last_proc = sc_get_last_created_process_handle();
00298     if (!last_proc) return; 
00299     if (last_proc->is_cthread()) {
00300         SC_REPORT_WARNING( SC_ID_DONT_INITIALIZE_, 0 );
00301     } else {
00302   last_proc->do_initialize( false );
00303     }
00304 }
00305 
00306 
00307 // to generate unique names for objects in an MT-Safe way
00308 
00309 const char*
00310 sc_module::gen_unique_name( const char* basename_ )
00311 {
00312     return m_name_gen->gen_unique_name( basename_ );
00313 }
00314 
00315 
00316 // called by construction_done 
00317 
00318 void
00319 sc_module::before_end_of_elaboration()
00320 {}
00321 
00322 void
00323 sc_module::construction_done()
00324 {
00325     before_end_of_elaboration();
00326 }
00327 
00328 // called by elaboration_done (does nothing by default)
00329 
00330 void
00331 sc_module::end_of_elaboration()
00332 {}
00333 
00334 
00335 void
00336 sc_module::elaboration_done( bool& error_ )
00337 {
00338     if( ! m_end_module_called ) {
00339   char msg[BUFSIZ];
00340   sprintf( msg, "module '%s'", name() );
00341   SC_REPORT_WARNING( SC_ID_END_MODULE_NOT_CALLED_, msg );
00342   if( error_ ) {
00343       SC_REPORT_WARNING( SC_ID_HIER_NAME_INCORRECT_, 0 );
00344   }
00345   error_ = true;
00346     }
00347     end_of_elaboration();
00348 }
00349 
00350 // called by start_simulation (does nothing by default)
00351 
00352 void
00353 sc_module::start_of_simulation()
00354 {}
00355 
00356 void
00357 sc_module::start_simulation()
00358 {
00359     start_of_simulation();
00360 }
00361 
00362 // called by simulation_done (does nothing by default)
00363 
00364 void
00365 sc_module::end_of_simulation()
00366 {}
00367 
00368 void
00369 sc_module::simulation_done()
00370 {
00371     end_of_simulation();
00372 }
00373 
00374 void
00375 sc_module::set_stack_size( size_t size )
00376 {
00377     sc_process_b*    proc_p;    // Current process.
00378     sc_thread_handle thread_h;  // Current process as thread.
00379 
00380     proc_p = (simcontext()->is_running()) ?
00381   sc_get_curr_process_handle() :
00382   sc_get_last_created_process_handle();
00383 
00384     thread_h = DCAST<sc_thread_handle>(proc_p);
00385     if ( thread_h ) 
00386     {
00387   thread_h->set_stack_size( size );
00388     }
00389     else
00390     {
00391   SC_REPORT_WARNING( SC_ID_SET_STACK_SIZE_, 0 );
00392     }
00393 }
00394 
00395 
00396 int
00397 sc_module::append_port( sc_port_base* port_ )
00398 {
00399     int index = m_port_vec->size();
00400     m_port_vec->push_back( port_ );
00401     return index;
00402 }
00403 
00404 
00405 // positional binding methods
00406 
00407 sc_module&
00408 sc_module::operator << ( sc_interface& interface_ )
00409 {
00410     if( m_port_index == m_port_vec->size() ) {
00411   char msg[BUFSIZ];
00412   if( m_port_index == 0 ) {
00413       sprintf( msg, "module `%s' has no ports", name() );
00414   } else {
00415       sprintf( msg, "all ports of module `%s' are bound", name() );
00416   }
00417   SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
00418     }
00419     int status = (*m_port_vec)[m_port_index]->pbind( interface_ );
00420     if( status != 0 ) {
00421   char msg[BUFSIZ];
00422   switch( status ) {
00423   case 1:
00424       sprintf( msg, "port %d of module `%s' is already bound",
00425          m_port_index, name() );
00426       break;
00427   case 2:
00428       sprintf( msg, "type mismatch on port %d of module `%s'",
00429          m_port_index, name() );
00430       break;
00431   default:
00432       sprintf( msg, "unknown error" );
00433       break;
00434   }
00435   SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
00436     }
00437     ++ m_port_index;
00438     return *this;
00439 }
00440 
00441 sc_module&
00442 sc_module::operator << ( sc_port_base& port_ )
00443 {
00444     if( m_port_index == m_port_vec->size() ) {
00445   char msg[BUFSIZ];
00446   if( m_port_index == 0 ) {
00447       sprintf( msg, "module `%s' has no ports", name() );
00448   } else {
00449       sprintf( msg, "all ports of module `%s' are bound", name() );
00450   }
00451   SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
00452     }
00453     int status = (*m_port_vec)[m_port_index]->pbind( port_ );
00454     if( status != 0 ) {
00455   char msg[BUFSIZ];
00456   switch( status ) {
00457   case 1:
00458       sprintf( msg, "port %d of module `%s' is already bound",
00459          m_port_index, name() );
00460       break;
00461   case 2:
00462       sprintf( msg, "type mismatch on port %d of module `%s'",
00463          m_port_index, name() );
00464       break;
00465   default:
00466       sprintf( msg, "unknown error" );
00467       break;
00468   }
00469   SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
00470     }
00471     ++ m_port_index;
00472     return *this;
00473 }
00474 
00475 
00476 #define TRY_BIND( p )                                                         \
00477     if( (p).iface != 0 ) {                                                    \
00478         operator << ( *(p).iface );                                           \
00479     } else if( (p).port != 0 ) {                                              \
00480         operator << ( *(p).port );                                            \
00481     } else {                                                                  \
00482         return;                                                               \
00483     }
00484 
00485 
00486 void
00487 sc_module::operator () ( const sc_bind_proxy& p001,
00488        const sc_bind_proxy& p002,
00489        const sc_bind_proxy& p003,
00490        const sc_bind_proxy& p004,
00491        const sc_bind_proxy& p005,
00492        const sc_bind_proxy& p006,
00493        const sc_bind_proxy& p007,
00494        const sc_bind_proxy& p008,
00495        const sc_bind_proxy& p009,
00496        const sc_bind_proxy& p010,
00497        const sc_bind_proxy& p011,
00498        const sc_bind_proxy& p012,
00499        const sc_bind_proxy& p013,
00500        const sc_bind_proxy& p014,
00501        const sc_bind_proxy& p015,
00502        const sc_bind_proxy& p016,
00503        const sc_bind_proxy& p017,
00504        const sc_bind_proxy& p018,
00505        const sc_bind_proxy& p019,
00506        const sc_bind_proxy& p020,
00507        const sc_bind_proxy& p021,
00508        const sc_bind_proxy& p022,
00509        const sc_bind_proxy& p023,
00510        const sc_bind_proxy& p024,
00511        const sc_bind_proxy& p025,
00512        const sc_bind_proxy& p026,
00513        const sc_bind_proxy& p027,
00514        const sc_bind_proxy& p028,
00515        const sc_bind_proxy& p029,
00516        const sc_bind_proxy& p030,
00517        const sc_bind_proxy& p031,
00518        const sc_bind_proxy& p032,
00519        const sc_bind_proxy& p033,
00520        const sc_bind_proxy& p034,
00521        const sc_bind_proxy& p035,
00522        const sc_bind_proxy& p036,
00523        const sc_bind_proxy& p037,
00524        const sc_bind_proxy& p038,
00525        const sc_bind_proxy& p039,
00526        const sc_bind_proxy& p040,
00527        const sc_bind_proxy& p041,
00528        const sc_bind_proxy& p042,
00529        const sc_bind_proxy& p043,
00530        const sc_bind_proxy& p044,
00531        const sc_bind_proxy& p045,
00532        const sc_bind_proxy& p046,
00533        const sc_bind_proxy& p047,
00534        const sc_bind_proxy& p048,
00535        const sc_bind_proxy& p049,
00536        const sc_bind_proxy& p050,
00537        const sc_bind_proxy& p051,
00538        const sc_bind_proxy& p052,
00539        const sc_bind_proxy& p053,
00540        const sc_bind_proxy& p054,
00541        const sc_bind_proxy& p055,
00542        const sc_bind_proxy& p056,
00543        const sc_bind_proxy& p057,
00544        const sc_bind_proxy& p058,
00545        const sc_bind_proxy& p059,
00546        const sc_bind_proxy& p060,
00547        const sc_bind_proxy& p061,
00548        const sc_bind_proxy& p062,
00549        const sc_bind_proxy& p063,
00550        const sc_bind_proxy& p064 )
00551 {
00552     TRY_BIND( p001 );
00553     TRY_BIND( p002 );
00554     TRY_BIND( p003 );
00555     TRY_BIND( p004 );
00556     TRY_BIND( p005 );
00557     TRY_BIND( p006 );
00558     TRY_BIND( p007 );
00559     TRY_BIND( p008 );
00560     TRY_BIND( p009 );
00561     TRY_BIND( p010 );
00562     TRY_BIND( p011 );
00563     TRY_BIND( p012 );
00564     TRY_BIND( p013 );
00565     TRY_BIND( p014 );
00566     TRY_BIND( p015 );
00567     TRY_BIND( p016 );
00568     TRY_BIND( p017 );
00569     TRY_BIND( p018 );
00570     TRY_BIND( p019 );
00571     TRY_BIND( p020 );
00572     TRY_BIND( p021 );
00573     TRY_BIND( p022 );
00574     TRY_BIND( p023 );
00575     TRY_BIND( p024 );
00576     TRY_BIND( p025 );
00577     TRY_BIND( p026 );
00578     TRY_BIND( p027 );
00579     TRY_BIND( p028 );
00580     TRY_BIND( p029 );
00581     TRY_BIND( p030 );
00582     TRY_BIND( p031 );
00583     TRY_BIND( p032 );
00584     TRY_BIND( p033 );
00585     TRY_BIND( p034 );
00586     TRY_BIND( p035 );
00587     TRY_BIND( p036 );
00588     TRY_BIND( p037 );
00589     TRY_BIND( p038 );
00590     TRY_BIND( p039 );
00591     TRY_BIND( p040 );
00592     TRY_BIND( p041 );
00593     TRY_BIND( p042 );
00594     TRY_BIND( p043 );
00595     TRY_BIND( p044 );
00596     TRY_BIND( p045 );
00597     TRY_BIND( p046 );
00598     TRY_BIND( p047 );
00599     TRY_BIND( p048 );
00600     TRY_BIND( p049 );
00601     TRY_BIND( p050 );
00602     TRY_BIND( p051 );
00603     TRY_BIND( p052 );
00604     TRY_BIND( p053 );
00605     TRY_BIND( p054 );
00606     TRY_BIND( p055 );
00607     TRY_BIND( p056 );
00608     TRY_BIND( p057 );
00609     TRY_BIND( p058 );
00610     TRY_BIND( p059 );
00611     TRY_BIND( p060 );
00612     TRY_BIND( p061 );
00613     TRY_BIND( p062 );
00614     TRY_BIND( p063 );
00615     TRY_BIND( p064 );
00616 }
00617 
00618 
00619 // Taf!

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