sc_module.h

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-2006 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.4 (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.h -- Base class of all hierarchical modules and channels.
00021 
00022   Original Author: Stan Y. Liao, Synopsys, Inc.
00023                    Martin Janssen, Synopsys, Inc.
00024 
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028 
00029   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00030   changes you are making here.
00031 
00032       Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
00033   Description of Modification: - Implementation of operator() and operator,
00034                                  positional connection method.
00035                                - Implementation of error checking in
00036                                  operator<<'s.
00037                                - Implementation of the function test_module_prm.
00038                                - Implementation of set_stack_size().
00039 
00040       Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc.
00041   Description of Modification: - Change implementation for VC6.
00042 
00043       Name, Affiliation, Date: Andy Godorich, Forte
00044                                Bishnupriya Bhattacharya, Cadence Design Systems,
00045                                25 August, 2003
00046   Description of Modification: inherit from sc_process_host as a part of
00047                                implementing dynamic processes
00048 
00049  *****************************************************************************/
00050 
00051 // $Log: sc_module.h,v $
00052 // Revision 1.3  2007/03/14 17:48:04  acg
00053 //  Andy Goodrich: Fixed this-> usage in process macros.
00054 //
00055 // Revision 1.2  2007/01/24 20:14:12  acg
00056 //  Andy Goodrich: improved comment about using this-> in the macros that
00057 //  access sensitive.
00058 //
00059 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00060 // SystemC 2.2
00061 //
00062 // Revision 1.7  2006/04/11 23:13:21  acg
00063 //   Andy Goodrich: Changes for reduced reset support that only includes
00064 //   sc_cthread, but has preliminary hooks for expanding to method and thread
00065 //   processes also.
00066 //
00067 // Revision 1.6  2006/03/15 17:53:34  acg
00068 //  Andy Goodrich, Forte Design
00069 //  Reordered includes to pick up <cassert> for use by sc_process_name.h
00070 //
00071 // Revision 1.5  2006/03/14 23:56:58  acg
00072 //   Andy Goodrich: This fixes a bug when an exception is thrown in
00073 //   sc_module::sc_module() for a dynamically allocated sc_module
00074 //   object. We are calling sc_module::end_module() on a module that has
00075 //   already been deleted. The scenario runs like this:
00076 //
00077 //   a) the sc_module constructor is entered
00078 //   b) the exception is thrown
00079 //   c) the exception processor deletes the storage for the sc_module
00080 //   d) the stack is unrolled causing the sc_module_name instance to be deleted
00081 //   e) ~sc_module_name() calls end_module() with its pointer to the sc_module
00082 //   f) because the sc_module has been deleted its storage is corrupted,
00083 //      either by linking it to a free space chain, or by reuse of some sort
00084 //   g) the m_simc field is garbage
00085 //   h) the m_object_manager field is also garbage
00086 //   i) an exception occurs
00087 //
00088 //   This does not happen for automatic sc_module instances since the
00089 //   storage for the module is not reclaimed its just part of the stack.
00090 //
00091 //   I am fixing this by having the destructor for sc_module clear the
00092 //   module pointer in its sc_module_name instance. That cuts things at
00093 //   step (e) above, since the pointer will be null if the module has
00094 //   already been deleted. To make sure the module stack is okay, I call
00095 //   end-module() in ~sc_module in the case where there is an
00096 //   sc_module_name pointer lying around.
00097 //
00098 // Revision 1.4  2006/01/24 20:49:05  acg
00099 // Andy Goodrich: changes to remove the use of deprecated features within the
00100 // simulator, and to issue warning messages when deprecated features are used.
00101 //
00102 // Revision 1.3  2006/01/13 18:44:30  acg
00103 // Added $Log to record CVS changes into the source.
00104 //
00105 
00106 #ifndef SC_MODULE_H
00107 #define SC_MODULE_H
00108 
00109 #include "sysc/kernel/sc_kernel_ids.h"
00110 #include "sysc/kernel/sc_process.h"
00111 #include "sysc/kernel/sc_module_name.h"
00112 #include "sysc/kernel/sc_sensitive.h"
00113 #include "sysc/kernel/sc_time.h"
00114 #include "sysc/kernel/sc_wait.h"
00115 #include "sysc/kernel/sc_wait_cthread.h"
00116 #include "sysc/kernel/sc_process.h"
00117 #include "sysc/kernel/sc_process_handle.h"
00118 #include "sysc/utils/sc_list.h"
00119 #include "sysc/utils/sc_string.h"
00120 
00121 namespace sc_core {
00122 
00123 class sc_name_gen;
00124 template<class T> class sc_in;
00125 template<class T> class sc_signal;
00126 
00127 // ----------------------------------------------------------------------------
00128 //  STRUCT : sc_bind_proxy
00129 //
00130 //  Struct for temporarily storing a pointer to an interface or port.
00131 //  Used for positional binding.
00132 // ----------------------------------------------------------------------------
00133 
00134 struct sc_bind_proxy
00135 {
00136     sc_interface* iface;
00137     sc_port_base* port;
00138     
00139     sc_bind_proxy();
00140     sc_bind_proxy( sc_interface& );
00141     sc_bind_proxy( sc_port_base& );
00142 };
00143 
00144 
00145 extern const sc_bind_proxy SC_BIND_PROXY_NIL;
00146 
00147 
00148 // ----------------------------------------------------------------------------
00149 //  CLASS : sc_module
00150 //
00151 //  Base class for all structural entities.
00152 // ----------------------------------------------------------------------------
00153 
00154 class sc_module
00155 : public sc_object, public sc_process_host
00156 {
00157     friend class sc_module_name;
00158     friend class sc_module_registry;
00159     friend class sc_object;
00160     friend class sc_port_registry;
00161     friend class sc_process_b;
00162     friend class sc_simcontext;
00163 
00164 public:
00165 
00166     sc_simcontext* sc_get_curr_simcontext()
00167     { return simcontext(); }
00168 
00169     // to generate unique names for objects in an MT-Safe way
00170     const char* gen_unique_name( const char* basename_, bool preserve_first );
00171 
00172     virtual const char* kind() const
00173         { return "sc_module"; }
00174 
00175 protected:
00176   
00177     // called by construction_done 
00178     virtual void before_end_of_elaboration();
00179 
00180     void construction_done();
00181 
00182     // called by elaboration_done (does nothing by default)
00183     virtual void end_of_elaboration();
00184 
00185     void elaboration_done( bool& );
00186 
00187     // called by start_simulation (does nothing by default)
00188     virtual void start_of_simulation();
00189 
00190     void start_simulation();
00191 
00192     // called by simulation_done (does nothing by default)
00193     virtual void end_of_simulation();
00194 
00195     void simulation_done();
00196 
00197     void sc_module_init();
00198 
00199     // constructor
00200     sc_module( const char* nm );
00201     sc_module( const std::string& nm );
00202     sc_module( const sc_module_name& nm ); /* for those used to old style */
00203     sc_module();
00204 
00205 public:
00206 
00207     // destructor
00208     virtual ~sc_module();
00209 
00210     // positional binding methods
00211 
00212     sc_module& operator << ( sc_interface& );
00213     sc_module& operator << ( sc_port_base& );
00214 
00215     sc_module& operator , ( sc_interface& interface_ )
00216         { return operator << ( interface_ ); }
00217 
00218     sc_module& operator , ( sc_port_base& port_ )
00219         { return operator << ( port_ ); }
00220 
00221     // operator() is declared at the end of the class.
00222 
00223     const ::std::vector<sc_object*>& get_child_objects() const;
00224 
00225 protected:
00226 
00227     void add_child_object( sc_object* );
00228     void remove_child_object( sc_object* );
00229 
00230     // this must be called by user-defined modules
00231     void end_module();
00232 
00233 
00234     // to prevent initialization for SC_METHODs and SC_THREADs
00235     void dont_initialize();
00236 
00237     // positional binding code - used by operator ()
00238 
00239     void positional_bind( sc_interface& );
00240     void positional_bind( sc_port_base& );
00241 
00242     // set reset sensitivity for SC_CTHREADs
00243     void reset_signal_is( const sc_in<bool>& port, bool level );
00244     void reset_signal_is( const sc_signal_in_if<bool>& iface, bool level );
00245 
00246     // static sensitivity for SC_THREADs and SC_CTHREADs
00247 
00248     void wait()
00249         { ::sc_core::wait( simcontext() ); }
00250 
00251     // dynamic sensitivity for SC_THREADs and SC_CTHREADs
00252 
00253     void wait( const sc_event& e )
00254         { ::sc_core::wait( e, simcontext() ); }
00255 
00256     void wait( sc_event_or_list& el )
00257     { ::sc_core::wait( el, simcontext() ); }
00258 
00259     void wait( sc_event_and_list& el )
00260     { ::sc_core::wait( el, simcontext() ); }
00261 
00262     void wait( const sc_time& t )
00263         { ::sc_core::wait( t, simcontext() ); }
00264 
00265     void wait( double v, sc_time_unit tu )
00266         { ::sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
00267 
00268     void wait( const sc_time& t, const sc_event& e )
00269         { ::sc_core::wait( t, e, simcontext() ); }
00270 
00271     void wait( double v, sc_time_unit tu, const sc_event& e )
00272         { ::sc_core::wait( 
00273         sc_time( v, tu, simcontext() ), e, simcontext() ); }
00274 
00275     void wait( const sc_time& t, sc_event_or_list& el )
00276         { ::sc_core::wait( t, el, simcontext() ); }
00277 
00278     void wait( double v, sc_time_unit tu, sc_event_or_list& el )
00279         { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
00280 
00281     void wait( const sc_time& t, sc_event_and_list& el )
00282         { ::sc_core::wait( t, el, simcontext() ); }
00283 
00284     void wait( double v, sc_time_unit tu, sc_event_and_list& el )
00285         { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
00286 
00287 
00288     // static sensitivity for SC_METHODs
00289 
00290     void next_trigger()
00291     { ::sc_core::next_trigger( simcontext() ); }
00292 
00293 
00294     // dynamic sensitivty for SC_METHODs
00295 
00296     void next_trigger( const sc_event& e )
00297         { ::sc_core::next_trigger( e, simcontext() ); }
00298 
00299     void next_trigger( sc_event_or_list& el )
00300         { ::sc_core::next_trigger( el, simcontext() ); }
00301 
00302     void next_trigger( sc_event_and_list& el )
00303         { ::sc_core::next_trigger( el, simcontext() ); }
00304 
00305     void next_trigger( const sc_time& t )
00306         { ::sc_core::next_trigger( t, simcontext() ); }
00307 
00308     void next_trigger( double v, sc_time_unit tu )
00309         { ::sc_core::next_trigger( 
00310         sc_time( v, tu, simcontext() ), simcontext() ); }
00311 
00312     void next_trigger( const sc_time& t, const sc_event& e )
00313         { ::sc_core::next_trigger( t, e, simcontext() ); }
00314 
00315     void next_trigger( double v, sc_time_unit tu, const sc_event& e )
00316         { ::sc_core::next_trigger( 
00317         sc_time( v, tu, simcontext() ), e, simcontext() ); }
00318 
00319     void next_trigger( const sc_time& t, sc_event_or_list& el )
00320         { ::sc_core::next_trigger( t, el, simcontext() ); }
00321 
00322     void next_trigger( double v, sc_time_unit tu, sc_event_or_list& el )
00323         { ::sc_core::next_trigger( 
00324         sc_time( v, tu, simcontext() ), el, simcontext() ); }
00325 
00326     void next_trigger( const sc_time& t, sc_event_and_list& el )
00327         { ::sc_core::next_trigger( t, el, simcontext() ); }
00328 
00329     void next_trigger( double v, sc_time_unit tu, sc_event_and_list& el )
00330         { ::sc_core::next_trigger( 
00331         sc_time( v, tu, simcontext() ), el, simcontext() ); }
00332 
00333 
00334     // for SC_METHODs and SC_THREADs and SC_CTHREADs
00335 
00336     bool timed_out()
00337         { return ::sc_core::timed_out(); }
00338 
00339 
00340     // for SC_CTHREADs
00341 
00342     void halt()
00343         { ::sc_core::halt( simcontext() ); }
00344 
00345     void wait( int n )
00346         { ::sc_core::wait( n, simcontext() ); }
00347 
00348     void at_posedge( const sc_signal_in_if<bool>& s )
00349     { ::sc_core::at_posedge( s, simcontext() ); }
00350 
00351     void at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
00352     { ::sc_core::at_posedge( s, simcontext() ); }
00353 
00354     void at_negedge( const sc_signal_in_if<bool>& s )
00355     { ::sc_core::at_negedge( s, simcontext() ); }
00356 
00357     void at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
00358     { ::sc_core::at_negedge( s, simcontext() ); }
00359 
00360     // Catch uses of watching:
00361     void watching( bool expr )
00362         { SC_REPORT_ERROR(SC_ID_WATCHING_NOT_ALLOWED_,""); }
00363 
00364     // These are protected so that user derived classes can refer to them.
00365     sc_sensitive     sensitive;
00366     sc_sensitive_pos sensitive_pos;
00367     sc_sensitive_neg sensitive_neg;
00368 
00369     // Function to set the stack size of the current (c)thread process.
00370     void set_stack_size( std::size_t );
00371 
00372     int append_port( sc_port_base* );
00373 
00374 private:
00375     sc_module( const sc_module& );
00376 
00377 private:
00378 
00379     bool                        m_end_module_called;
00380     std::vector<sc_port_base*>* m_port_vec;
00381     int                         m_port_index;
00382     sc_name_gen*                m_name_gen;
00383     std::vector<sc_object*>     m_child_objects;
00384     sc_module_name*             m_module_name_p;
00385 
00386 public:
00387 
00388     void defunct() { }
00389 
00390     // positional binding methods (cont'd)
00391 
00392     void operator () ( const sc_bind_proxy& p001,
00393                const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL,
00394                const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL,
00395                const sc_bind_proxy& p004 = SC_BIND_PROXY_NIL,
00396                const sc_bind_proxy& p005 = SC_BIND_PROXY_NIL,
00397                const sc_bind_proxy& p006 = SC_BIND_PROXY_NIL,
00398                const sc_bind_proxy& p007 = SC_BIND_PROXY_NIL,
00399                const sc_bind_proxy& p008 = SC_BIND_PROXY_NIL,
00400                const sc_bind_proxy& p009 = SC_BIND_PROXY_NIL,
00401                const sc_bind_proxy& p010 = SC_BIND_PROXY_NIL,
00402                const sc_bind_proxy& p011 = SC_BIND_PROXY_NIL,
00403                const sc_bind_proxy& p012 = SC_BIND_PROXY_NIL,
00404                const sc_bind_proxy& p013 = SC_BIND_PROXY_NIL,
00405                const sc_bind_proxy& p014 = SC_BIND_PROXY_NIL,
00406                const sc_bind_proxy& p015 = SC_BIND_PROXY_NIL,
00407                const sc_bind_proxy& p016 = SC_BIND_PROXY_NIL,
00408                const sc_bind_proxy& p017 = SC_BIND_PROXY_NIL,
00409                const sc_bind_proxy& p018 = SC_BIND_PROXY_NIL,
00410                const sc_bind_proxy& p019 = SC_BIND_PROXY_NIL,
00411                const sc_bind_proxy& p020 = SC_BIND_PROXY_NIL,
00412                const sc_bind_proxy& p021 = SC_BIND_PROXY_NIL,
00413                const sc_bind_proxy& p022 = SC_BIND_PROXY_NIL,
00414                const sc_bind_proxy& p023 = SC_BIND_PROXY_NIL,
00415                const sc_bind_proxy& p024 = SC_BIND_PROXY_NIL,
00416                const sc_bind_proxy& p025 = SC_BIND_PROXY_NIL,
00417                const sc_bind_proxy& p026 = SC_BIND_PROXY_NIL,
00418                const sc_bind_proxy& p027 = SC_BIND_PROXY_NIL,
00419                const sc_bind_proxy& p028 = SC_BIND_PROXY_NIL,
00420                const sc_bind_proxy& p029 = SC_BIND_PROXY_NIL,
00421                const sc_bind_proxy& p030 = SC_BIND_PROXY_NIL,
00422                const sc_bind_proxy& p031 = SC_BIND_PROXY_NIL,
00423                const sc_bind_proxy& p032 = SC_BIND_PROXY_NIL,
00424                const sc_bind_proxy& p033 = SC_BIND_PROXY_NIL,
00425                const sc_bind_proxy& p034 = SC_BIND_PROXY_NIL,
00426                const sc_bind_proxy& p035 = SC_BIND_PROXY_NIL,
00427                const sc_bind_proxy& p036 = SC_BIND_PROXY_NIL,
00428                const sc_bind_proxy& p037 = SC_BIND_PROXY_NIL,
00429                const sc_bind_proxy& p038 = SC_BIND_PROXY_NIL,
00430                const sc_bind_proxy& p039 = SC_BIND_PROXY_NIL,
00431                const sc_bind_proxy& p040 = SC_BIND_PROXY_NIL,
00432                const sc_bind_proxy& p041 = SC_BIND_PROXY_NIL,
00433                const sc_bind_proxy& p042 = SC_BIND_PROXY_NIL,
00434                const sc_bind_proxy& p043 = SC_BIND_PROXY_NIL,
00435                const sc_bind_proxy& p044 = SC_BIND_PROXY_NIL,
00436                const sc_bind_proxy& p045 = SC_BIND_PROXY_NIL,
00437                const sc_bind_proxy& p046 = SC_BIND_PROXY_NIL,
00438                const sc_bind_proxy& p047 = SC_BIND_PROXY_NIL,
00439                const sc_bind_proxy& p048 = SC_BIND_PROXY_NIL,
00440                const sc_bind_proxy& p049 = SC_BIND_PROXY_NIL,
00441                const sc_bind_proxy& p050 = SC_BIND_PROXY_NIL,
00442                const sc_bind_proxy& p051 = SC_BIND_PROXY_NIL,
00443                const sc_bind_proxy& p052 = SC_BIND_PROXY_NIL,
00444                const sc_bind_proxy& p053 = SC_BIND_PROXY_NIL,
00445                const sc_bind_proxy& p054 = SC_BIND_PROXY_NIL,
00446                const sc_bind_proxy& p055 = SC_BIND_PROXY_NIL,
00447                const sc_bind_proxy& p056 = SC_BIND_PROXY_NIL,
00448                const sc_bind_proxy& p057 = SC_BIND_PROXY_NIL,
00449                const sc_bind_proxy& p058 = SC_BIND_PROXY_NIL,
00450                const sc_bind_proxy& p059 = SC_BIND_PROXY_NIL,
00451                const sc_bind_proxy& p060 = SC_BIND_PROXY_NIL,
00452                const sc_bind_proxy& p061 = SC_BIND_PROXY_NIL,
00453                const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL,
00454                const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL,
00455                const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL );
00456 
00457 };
00458 
00459 extern sc_module* sc_module_dynalloc(sc_module*);
00460 #define SC_NEW(x)  ::sc_core::sc_module_dynalloc(new x);
00461 
00462 
00463 // -----------------------------------------------------------------------------
00464 // SOME MACROS TO SIMPLIFY SYNTAX:
00465 // -----------------------------------------------------------------------------
00466 
00467 #define SC_MODULE(user_module_name)                                           \
00468     struct user_module_name : ::sc_core::sc_module
00469 
00470 #define SC_CTOR(user_module_name)                                             \
00471     typedef user_module_name SC_CURRENT_USER_MODULE;                          \
00472     user_module_name( ::sc_core::sc_module_name )
00473 
00474 // the SC_HAS_PROCESS macro call must be followed by a ;
00475 #define SC_HAS_PROCESS(user_module_name)                                      \
00476     typedef user_module_name SC_CURRENT_USER_MODULE
00477 
00478 // The this-> construct on sensitive operators in the macros below is
00479 // required for gcc 4.x when a templated class has a templated parent that is
00480 // derived from sc_module:
00481 //
00482 // template<typename X>
00483 // class B : public sc_module;
00484 // template<typename X>
00485 // class A : public B<X>
00486 
00487 
00488 #define declare_method_process(handle, name, host_tag, func)        \
00489     {                                                           \
00490         ::sc_core::sc_process_handle handle =                      \
00491         sc_core::sc_get_curr_simcontext()->create_method_process( \
00492         name,  false, SC_MAKE_FUNC_PTR( host_tag, func ), \
00493         this, 0 ); \
00494         this->sensitive << handle;                                        \
00495         this->sensitive_pos << handle;                                    \
00496         this->sensitive_neg << handle;                                    \
00497     }
00498 
00499 #define declare_thread_process(handle, name, host_tag, func)        \
00500     {                                                               \
00501         ::sc_core::sc_process_handle handle =                      \
00502          sc_core::sc_get_curr_simcontext()->create_thread_process( \
00503                  name,  false,           \
00504                  SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
00505         this->sensitive << handle;                                        \
00506         this->sensitive_pos << handle;                                    \
00507         this->sensitive_neg << handle;                                    \
00508     }
00509 
00510 #define declare_cthread_process(handle, name, host_tag, func, edge) \
00511     {                                                               \
00512         ::sc_core::sc_process_handle handle =                     \
00513          sc_core::sc_get_curr_simcontext()->create_cthread_process( \
00514             name,  false,          \
00515                      SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
00516         this->sensitive.operator() ( handle, edge );\
00517     }
00518 
00519 #define SC_CTHREAD(func, edge)                                                \
00520     declare_cthread_process( func ## _handle,                                 \
00521                              #func,                                           \
00522                              SC_CURRENT_USER_MODULE,                          \
00523                              func,                                            \
00524                              edge )
00525 
00526 #define SC_METHOD(func)                                                       \
00527     declare_method_process( func ## _handle,                                  \
00528                             #func,                                            \
00529                             SC_CURRENT_USER_MODULE,                           \
00530                             func )
00531 
00532 #define SC_THREAD(func)                                                       \
00533     declare_thread_process( func ## _handle,                                  \
00534                             #func,                                            \
00535                             SC_CURRENT_USER_MODULE,                           \
00536                             func )
00537 
00538 
00539 
00540 // ----------------------------------------------------------------------------
00541 //  TYPEDEFS
00542 // ----------------------------------------------------------------------------
00543 
00544 typedef sc_module sc_channel;
00545 typedef sc_module sc_behavior;
00546 
00547 } // namespace sc_core
00548 
00549 #endif

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5