src/sysc/kernel/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-2005 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 #ifndef SC_MODULE_H
00052 #define SC_MODULE_H
00053 
00054 #include "sysc/kernel/sc_kernel_ids.h"
00055 #include "sysc/kernel/sc_lambda.h"
00056 #include "sysc/kernel/sc_module_name.h"
00057 #include "sysc/kernel/sc_process.h"
00058 #include "sysc/kernel/sc_sensitive.h"
00059 #include "sysc/kernel/sc_time.h"
00060 #include "sysc/kernel/sc_wait.h"
00061 #include "sysc/kernel/sc_wait_cthread.h"
00062 #include "sysc/kernel/sc_process_host.h"
00063 #include "sysc/utils/sc_list.h"
00064 #include "sysc/utils/sc_string.h"
00065 
00066 namespace sc_core {
00067 
00068 class sc_name_gen;
00069 template<class T> class sc_in;
00070 template<class T> class sc_signal;
00071 
00072 // ----------------------------------------------------------------------------
00073 //  STRUCT : sc_bind_proxy
00074 //
00075 //  Struct for temporarily storing a pointer to an interface or port.
00076 //  Used for positional binding.
00077 // ----------------------------------------------------------------------------
00078 
00079 struct sc_bind_proxy
00080 {
00081     sc_interface* iface;
00082     sc_port_base* port;
00083     
00084     sc_bind_proxy();
00085     sc_bind_proxy( sc_interface& );
00086     sc_bind_proxy( sc_port_base& );
00087 };
00088 
00089 
00090 extern const sc_bind_proxy SC_BIND_PROXY_NIL;
00091 
00092 
00093 // ----------------------------------------------------------------------------
00094 //  CLASS : sc_module
00095 //
00096 //  Base class for all structural entities.
00097 // ----------------------------------------------------------------------------
00098 
00099 class sc_module
00100 : public sc_process_host
00101 {
00102     friend class sc_module_name;
00103     friend class sc_module_registry;
00104     friend class sc_object;
00105     friend class sc_port_registry;
00106     friend class sc_simcontext;
00107 
00108 public:
00109 
00110     sc_simcontext* sc_get_curr_simcontext()
00111         { return simcontext(); }
00112 
00113     // to generate unique names for objects in an MT-Safe way
00114     const char* gen_unique_name( const char* basename_, bool preserve_first );
00115 
00116     virtual const char* kind() const
00117         { return "sc_module"; }
00118 
00119 protected:
00120   
00121     // called by construction_done 
00122     virtual void before_end_of_elaboration();
00123 
00124     void construction_done();
00125 
00126     // called by elaboration_done (does nothing by default)
00127     virtual void end_of_elaboration();
00128 
00129     void elaboration_done( bool& );
00130 
00131     // called by start_simulation (does nothing by default)
00132     virtual void start_of_simulation();
00133 
00134     void start_simulation();
00135 
00136     // called by simulation_done (does nothing by default)
00137     virtual void end_of_simulation();
00138 
00139     void simulation_done();
00140 
00141     void sc_module_init();
00142 
00143     // constructor
00144     sc_module( const char* nm );
00145     sc_module( const std::string& nm );
00146     sc_module( const sc_module_name& nm ); /* for those used to old style */
00147     sc_module();
00148 
00149 public:
00150 
00151     // destructor
00152     virtual ~sc_module();
00153 
00154     // positional binding methods
00155 
00156     sc_module& operator << ( sc_interface& );
00157     sc_module& operator << ( sc_port_base& );
00158 
00159     sc_module& operator , ( sc_interface& interface_ )
00160         { return operator << ( interface_ ); }
00161 
00162     sc_module& operator , ( sc_port_base& port_ )
00163         { return operator << ( port_ ); }
00164 
00165     // operator() is declared at the end of the class.
00166 
00167     const ::std::vector<sc_object*>& get_child_objects() const;
00168 
00169 protected:
00170 
00171     void add_child_object( sc_object* );
00172     void remove_child_object( sc_object* );
00173 
00174     // this must be called by user-defined modules
00175     void end_module();
00176 
00177 
00178     // to prevent initialization for SC_METHODs and SC_THREADs
00179     void dont_initialize();
00180 
00181     // set reset sensitivity for SC_CTHREADs
00182     void reset_signal_is( const sc_in<bool>& port, bool level );
00183     void reset_signal_is( const sc_signal<bool>& sig, bool level );
00184 
00185     // static sensitivity for SC_THREADs and SC_CTHREADs
00186 
00187     void wait()
00188         { ::sc_core::wait( simcontext() ); }
00189 
00190 
00191     // dynamic sensitivity for SC_THREADs and SC_CTHREADs
00192 
00193     void wait( const sc_event& e )
00194         { ::sc_core::wait( e, simcontext() ); }
00195 
00196     void wait( sc_event_or_list& el )
00197         { ::sc_core::wait( el, simcontext() ); }
00198 
00199     void wait( sc_event_and_list& el )
00200         { ::sc_core::wait( el, simcontext() ); }
00201 
00202     void wait( const sc_time& t )
00203         { ::sc_core::wait( t, simcontext() ); }
00204 
00205     void wait( double v, sc_time_unit tu )
00206         { ::sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
00207 
00208     void wait( const sc_time& t, const sc_event& e )
00209         { ::sc_core::wait( t, e, simcontext() ); }
00210 
00211     void wait( double v, sc_time_unit tu, const sc_event& e )
00212         { ::sc_core::wait( 
00213                 sc_time( v, tu, simcontext() ), e, simcontext() ); }
00214 
00215     void wait( const sc_time& t, sc_event_or_list& el )
00216         { ::sc_core::wait( t, el, simcontext() ); }
00217 
00218     void wait( double v, sc_time_unit tu, sc_event_or_list& el )
00219         { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
00220 
00221     void wait( const sc_time& t, sc_event_and_list& el )
00222         { ::sc_core::wait( t, el, simcontext() ); }
00223 
00224     void wait( double v, sc_time_unit tu, sc_event_and_list& el )
00225         { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
00226 
00227 
00228     // static sensitivity for SC_METHODs
00229 
00230     void next_trigger()
00231         { ::sc_core::next_trigger( simcontext() ); }
00232 
00233 
00234     // dynamic sensitivty for SC_METHODs
00235 
00236     void next_trigger( const sc_event& e )
00237         { ::sc_core::next_trigger( e, simcontext() ); }
00238 
00239     void next_trigger( sc_event_or_list& el )
00240         { ::sc_core::next_trigger( el, simcontext() ); }
00241 
00242     void next_trigger( sc_event_and_list& el )
00243         { ::sc_core::next_trigger( el, simcontext() ); }
00244 
00245     void next_trigger( const sc_time& t )
00246         { ::sc_core::next_trigger( t, simcontext() ); }
00247 
00248     void next_trigger( double v, sc_time_unit tu )
00249         { ::sc_core::next_trigger( 
00250             sc_time( v, tu, simcontext() ), simcontext() ); }
00251 
00252     void next_trigger( const sc_time& t, const sc_event& e )
00253         { ::sc_core::next_trigger( t, e, simcontext() ); }
00254 
00255     void next_trigger( double v, sc_time_unit tu, const sc_event& e )
00256         { ::sc_core::next_trigger( 
00257                 sc_time( v, tu, simcontext() ), e, simcontext() ); }
00258 
00259     void next_trigger( const sc_time& t, sc_event_or_list& el )
00260         { ::sc_core::next_trigger( t, el, simcontext() ); }
00261 
00262     void next_trigger( double v, sc_time_unit tu, sc_event_or_list& el )
00263         { ::sc_core::next_trigger( 
00264             sc_time( v, tu, simcontext() ), el, simcontext() ); }
00265 
00266     void next_trigger( const sc_time& t, sc_event_and_list& el )
00267         { ::sc_core::next_trigger( t, el, simcontext() ); }
00268 
00269     void next_trigger( double v, sc_time_unit tu, sc_event_and_list& el )
00270         { ::sc_core::next_trigger( 
00271             sc_time( v, tu, simcontext() ), el, simcontext() ); }
00272 
00273 
00274     // for SC_METHODs and SC_THREADs and SC_CTHREADs
00275 
00276     bool timed_out()
00277         { return ::sc_core::timed_out( simcontext() ); }
00278 
00279 
00280     // for SC_CTHREADs
00281 
00282     void halt()
00283         { ::sc_core::halt( simcontext() ); }
00284 
00285     void wait( int n )
00286         { ::sc_core::wait( n, simcontext() ); }
00287 
00288     void wait_until( const sc_lambda_ptr& l )
00289         { ::sc_core::wait_until( l, simcontext() ); }
00290 
00291     void wait_until( const sc_signal_bool_deval& s )
00292         { ::sc_core::wait_until( s, simcontext() ); }
00293 
00294     void at_posedge( const sc_signal_in_if<bool>& s )
00295         { ::sc_core::at_posedge( s, simcontext() ); }
00296 
00297     void at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
00298         { ::sc_core::at_posedge( s, simcontext() ); }
00299 
00300     void at_negedge( const sc_signal_in_if<bool>& s )
00301         { ::sc_core::at_negedge( s, simcontext() ); }
00302 
00303     void at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
00304         { ::sc_core::at_negedge( s, simcontext() ); }
00305 
00306     void watching( const sc_lambda_ptr& l )
00307         { ::sc_core::watching( l, simcontext() ); }
00308 
00309     void watching( const sc_signal_bool_deval& s )
00310         { ::sc_core::watching( s, simcontext() ); }
00311 
00312 
00313     // These are protected so that user derived classes can refer to them.
00314     sc_sensitive     sensitive;
00315     sc_sensitive_pos sensitive_pos;
00316     sc_sensitive_neg sensitive_neg;
00317 
00318     // Function to set the stack size of the current (c)thread process.
00319     void set_stack_size( size_t );
00320 
00321     int append_port( sc_port_base* );
00322 
00323 private:
00324     sc_module( const sc_module& );
00325 
00326 private:
00327 
00328     bool                       m_end_module_called;
00329     sc_pvector<sc_port_base*>* m_port_vec;
00330     int                        m_port_index;
00331     sc_name_gen*               m_name_gen;
00332     sc_pvector<sc_object*>     m_child_objects;
00333 
00334 public:
00335 
00336     void defunct() { }
00337 
00338     // positional binding methods (cont'd)
00339 
00340     void operator () ( const sc_bind_proxy& p001,
00341                        const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL,
00342                        const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL,
00343                        const sc_bind_proxy& p004 = SC_BIND_PROXY_NIL,
00344                        const sc_bind_proxy& p005 = SC_BIND_PROXY_NIL,
00345                        const sc_bind_proxy& p006 = SC_BIND_PROXY_NIL,
00346                        const sc_bind_proxy& p007 = SC_BIND_PROXY_NIL,
00347                        const sc_bind_proxy& p008 = SC_BIND_PROXY_NIL,
00348                        const sc_bind_proxy& p009 = SC_BIND_PROXY_NIL,
00349                        const sc_bind_proxy& p010 = SC_BIND_PROXY_NIL,
00350                        const sc_bind_proxy& p011 = SC_BIND_PROXY_NIL,
00351                        const sc_bind_proxy& p012 = SC_BIND_PROXY_NIL,
00352                        const sc_bind_proxy& p013 = SC_BIND_PROXY_NIL,
00353                        const sc_bind_proxy& p014 = SC_BIND_PROXY_NIL,
00354                        const sc_bind_proxy& p015 = SC_BIND_PROXY_NIL,
00355                        const sc_bind_proxy& p016 = SC_BIND_PROXY_NIL,
00356                        const sc_bind_proxy& p017 = SC_BIND_PROXY_NIL,
00357                        const sc_bind_proxy& p018 = SC_BIND_PROXY_NIL,
00358                        const sc_bind_proxy& p019 = SC_BIND_PROXY_NIL,
00359                        const sc_bind_proxy& p020 = SC_BIND_PROXY_NIL,
00360                        const sc_bind_proxy& p021 = SC_BIND_PROXY_NIL,
00361                        const sc_bind_proxy& p022 = SC_BIND_PROXY_NIL,
00362                        const sc_bind_proxy& p023 = SC_BIND_PROXY_NIL,
00363                        const sc_bind_proxy& p024 = SC_BIND_PROXY_NIL,
00364                        const sc_bind_proxy& p025 = SC_BIND_PROXY_NIL,
00365                        const sc_bind_proxy& p026 = SC_BIND_PROXY_NIL,
00366                        const sc_bind_proxy& p027 = SC_BIND_PROXY_NIL,
00367                        const sc_bind_proxy& p028 = SC_BIND_PROXY_NIL,
00368                        const sc_bind_proxy& p029 = SC_BIND_PROXY_NIL,
00369                        const sc_bind_proxy& p030 = SC_BIND_PROXY_NIL,
00370                        const sc_bind_proxy& p031 = SC_BIND_PROXY_NIL,
00371                        const sc_bind_proxy& p032 = SC_BIND_PROXY_NIL,
00372                        const sc_bind_proxy& p033 = SC_BIND_PROXY_NIL,
00373                        const sc_bind_proxy& p034 = SC_BIND_PROXY_NIL,
00374                        const sc_bind_proxy& p035 = SC_BIND_PROXY_NIL,
00375                        const sc_bind_proxy& p036 = SC_BIND_PROXY_NIL,
00376                        const sc_bind_proxy& p037 = SC_BIND_PROXY_NIL,
00377                        const sc_bind_proxy& p038 = SC_BIND_PROXY_NIL,
00378                        const sc_bind_proxy& p039 = SC_BIND_PROXY_NIL,
00379                        const sc_bind_proxy& p040 = SC_BIND_PROXY_NIL,
00380                        const sc_bind_proxy& p041 = SC_BIND_PROXY_NIL,
00381                        const sc_bind_proxy& p042 = SC_BIND_PROXY_NIL,
00382                        const sc_bind_proxy& p043 = SC_BIND_PROXY_NIL,
00383                        const sc_bind_proxy& p044 = SC_BIND_PROXY_NIL,
00384                        const sc_bind_proxy& p045 = SC_BIND_PROXY_NIL,
00385                        const sc_bind_proxy& p046 = SC_BIND_PROXY_NIL,
00386                        const sc_bind_proxy& p047 = SC_BIND_PROXY_NIL,
00387                        const sc_bind_proxy& p048 = SC_BIND_PROXY_NIL,
00388                        const sc_bind_proxy& p049 = SC_BIND_PROXY_NIL,
00389                        const sc_bind_proxy& p050 = SC_BIND_PROXY_NIL,
00390                        const sc_bind_proxy& p051 = SC_BIND_PROXY_NIL,
00391                        const sc_bind_proxy& p052 = SC_BIND_PROXY_NIL,
00392                        const sc_bind_proxy& p053 = SC_BIND_PROXY_NIL,
00393                        const sc_bind_proxy& p054 = SC_BIND_PROXY_NIL,
00394                        const sc_bind_proxy& p055 = SC_BIND_PROXY_NIL,
00395                        const sc_bind_proxy& p056 = SC_BIND_PROXY_NIL,
00396                        const sc_bind_proxy& p057 = SC_BIND_PROXY_NIL,
00397                        const sc_bind_proxy& p058 = SC_BIND_PROXY_NIL,
00398                        const sc_bind_proxy& p059 = SC_BIND_PROXY_NIL,
00399                        const sc_bind_proxy& p060 = SC_BIND_PROXY_NIL,
00400                        const sc_bind_proxy& p061 = SC_BIND_PROXY_NIL,
00401                        const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL,
00402                        const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL,
00403                        const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL );
00404 
00405 };
00406 
00407 extern sc_module* sc_module_dynalloc(sc_module*);
00408 #define SC_NEW(x)  ::sc_core::sc_module_dynalloc(new x);
00409 
00410 
00411 // -----------------------------------------------------------------------------
00412 // SOME MACROS TO SIMPLIFY SYNTAX:
00413 // -----------------------------------------------------------------------------
00414 
00415 #define SC_MODULE(user_module_name)                                           \
00416     struct user_module_name : ::sc_core::sc_module
00417 
00418 #define SC_CTOR(user_module_name)                                             \
00419     typedef user_module_name SC_CURRENT_USER_MODULE;                          \
00420     user_module_name( ::sc_core::sc_module_name )
00421 
00422 // the SC_HAS_PROCESS macro call must be followed by a ;
00423 #define SC_HAS_PROCESS(user_module_name)                                      \
00424     typedef user_module_name SC_CURRENT_USER_MODULE
00425 
00426 
00427 #define declare_method_process(handle, name, host_tag, func)        \
00428     {                                                               \
00429         ::sc_core::sc_method_process* handle =                      \
00430                 simcontext()->register_method_process( name,        \
00431                      SC_MAKE_FUNC_PTR( host_tag, func ), this );    \
00432         sensitive << handle;                  \
00433         sensitive_pos << handle;              \
00434         sensitive_neg << handle;              \
00435     }
00436 
00437 #define declare_thread_process(handle, name, host_tag, func)        \
00438     {                                                               \
00439         ::sc_core::sc_thread_process* handle =                      \
00440             simcontext()->register_thread_process( name,            \
00441             SC_MAKE_FUNC_PTR( host_tag, func ), this );             \
00442         sensitive << handle;                  \
00443         sensitive_pos << handle;              \
00444         sensitive_neg << handle;              \
00445     }
00446 
00447 #define declare_cthread_process(handle, name, host_tag, func, edge) \
00448     {                                                               \
00449         ::sc_core::sc_cthread_process* handle =                     \
00450             simcontext()->register_cthread_process(name,            \
00451             SC_MAKE_FUNC_PTR( host_tag, func ), this );             \
00452         sensitive.operator() ( handle, edge );\
00453     }
00454 
00455 #define SC_CTHREAD(func, edge)                                                \
00456     declare_cthread_process( func ## _handle,                                 \
00457                              #func,                                           \
00458                              SC_CURRENT_USER_MODULE,                          \
00459                              func,                                            \
00460                              edge )
00461 
00462 #define SC_METHOD(func)                                                       \
00463     declare_method_process( func ## _handle,                                  \
00464                             #func,                                            \
00465                             SC_CURRENT_USER_MODULE,                           \
00466                             func )
00467 
00468 #define SC_THREAD(func)                                                       \
00469     declare_thread_process( func ## _handle,                                  \
00470                             #func,                                            \
00471                             SC_CURRENT_USER_MODULE,                           \
00472                             func )
00473 
00474 
00475 
00476 // ----------------------------------------------------------------------------
00477 //  TYPEDEFS
00478 // ----------------------------------------------------------------------------
00479 
00480 typedef sc_module sc_channel;
00481 typedef sc_module sc_behavior;
00482 
00483 } // namespace sc_core
00484 
00485 #endif

Generated on Wed Apr 25 13:53:27 2007 for SystemC by  doxygen 1.5.1