sc_simcontext.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_simcontext.h -- Definition of the simulation context class.
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: Andy Goodrich, Forte Design Systems 20 May 2003
00033   Description of Modification: - phase callbacks
00034                                - sc_stop mode
00035 
00036       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00037                                25 August, 2003
00038   Description of Modification: - support for dynamic process
00039                                - support for sc export registry
00040                                - new member methods elaborate(), 
00041                  prepare_to_simulate(), and initial_crunch()
00042                  that are invoked by initialize() in that order
00043                                - add sc_get_last_created_process_handle() for 
00044                  use before simulation starts
00045                                
00046       Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
00047                                3 March, 2004
00048   Description of Modification: add sc_get_curr_process_kind()
00049 
00050       Name, Affiliation, Date: 
00051   Description of Modification: 
00052                                
00053  *****************************************************************************/
00054 // $Log: sc_simcontext.h,v $
00055 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00056 // SystemC 2.2
00057 //
00058 // Revision 1.11  2006/04/11 23:13:21  acg
00059 //   Andy Goodrich: Changes for reduced reset support that only includes
00060 //   sc_cthread, but has preliminary hooks for expanding to method and thread
00061 //   processes also.
00062 //
00063 // Revision 1.10  2006/03/21 00:00:34  acg
00064 //   Andy Goodrich: changed name of sc_get_current_process_base() to be
00065 //   sc_get_current_process_b() since its returning an sc_process_b instance.
00066 //
00067 // Revision 1.9  2006/01/26 21:04:54  acg
00068 //  Andy Goodrich: deprecation message changes and additional messages.
00069 //
00070 // Revision 1.8  2006/01/24 20:49:05  acg
00071 // Andy Goodrich: changes to remove the use of deprecated features within the
00072 // simulator, and to issue warning messages when deprecated features are used.
00073 //
00074 // Revision 1.7  2006/01/19 00:29:52  acg
00075 // Andy Goodrich: Yet another implementation for signal write checking. This
00076 // one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
00077 // DISABLE will disable write checking on signals.
00078 //
00079 // Revision 1.6  2006/01/18 21:42:37  acg
00080 // Andy Goodrich: Changes for check writer support.
00081 //
00082 // Revision 1.5  2006/01/13 18:44:30  acg
00083 // Added $Log to record CVS changes into the source.
00084 //
00085 // Revision 1.4  2006/01/03 23:18:44  acg
00086 // Changed copyright to include 2006.
00087 //
00088 // Revision 1.3  2005/12/20 22:11:10  acg
00089 // Fixed $Log lines.
00090 //
00091 // Revision 1.2  2005/12/20 22:02:30  acg
00092 // Changed where delta cycles are incremented to match IEEE 1666. Added the
00093 // event_occurred() method to hide how delta cycle comparisions are done within
00094 // sc_simcontext. Changed the boolean update_phase to an enum that shows all
00095 // the phases.
00096 
00097 #ifndef SC_SIMCONTEXT_H
00098 #define SC_SIMCONTEXT_H
00099 
00100 #include "sysc/kernel/sc_cmnhdr.h"
00101 #include "sysc/kernel/sc_process.h"
00102 #include "sysc/kernel/sc_time.h"
00103 #include "sysc/utils/sc_hash.h"
00104 #include "sysc/utils/sc_pq.h"
00105 
00106 namespace sc_core {
00107 
00108 // forward declarations
00109 
00110 class sc_cor;
00111 class sc_cor_pkg;
00112 class sc_event;
00113 class sc_event_timed;
00114 class sc_export_registry;
00115 class sc_module;
00116 class sc_module_name;
00117 class sc_module_registry;
00118 class sc_name_gen;
00119 class sc_object;
00120 class sc_object_manager;
00121 class sc_process_handle;
00122 class sc_port_registry;
00123 class sc_prim_channel_registry;
00124 class sc_process_table;
00125 class sc_signal_bool_deval;
00126 class sc_trace_file;
00127 class sc_runnable;
00128 class sc_process_host;
00129 
00130 
00131 
00132 struct sc_curr_proc_info
00133 {
00134     sc_process_b*     process_handle;
00135     sc_curr_proc_kind kind;
00136     sc_curr_proc_info() : process_handle( 0 ), kind( SC_NO_PROC_ ) {}
00137 };
00138 
00139 typedef const sc_curr_proc_info* sc_curr_proc_handle;
00140 
00141 // friend function declarations
00142 
00143 sc_dt::uint64 sc_delta_count();
00144 const std::vector<sc_object*>& sc_get_top_level_objects(
00145 const sc_simcontext* simc_p);
00146 bool sc_is_running( const sc_simcontext* simc_p );
00147 bool sc_end_of_simulation_invoked();
00148 bool sc_start_of_simulation_invoked();
00149 void    sc_set_time_resolution( double, sc_time_unit );
00150 sc_time sc_get_time_resolution();
00151 void    sc_set_default_time_unit( double, sc_time_unit );
00152 sc_time sc_get_default_time_unit();
00153 bool sc_pending_activity_at_current_time();
00154 
00155 // simulation status codes
00156 
00157 const int SC_SIM_OK        = 0;
00158 const int SC_SIM_ERROR     = 1;
00159 const int SC_SIM_USER_STOP = 2;
00160 
00161 enum sc_stop_mode {          // sc_stop modes:
00162     SC_STOP_FINISH_DELTA,
00163     SC_STOP_IMMEDIATE
00164 };
00165 extern void sc_set_stop_mode( sc_stop_mode mode );
00166 extern sc_stop_mode sc_get_stop_mode();
00167 
00168 
00169 // ----------------------------------------------------------------------------
00170 //  CLASS : sc_simcontext
00171 //
00172 //  The simulation context.
00173 // ----------------------------------------------------------------------------
00174 
00175 class sc_simcontext
00176 {
00177     friend class sc_event;
00178     friend class sc_module;
00179     friend class sc_object;
00180     friend class sc_time;
00181     friend class sc_clock;
00182     friend class sc_method_process;
00183     friend class sc_process_b;
00184     friend class sc_prim_channel;
00185     friend class sc_thread_process;
00186     friend sc_dt::uint64 sc_delta_count();
00187     friend const std::vector<sc_object*>& sc_get_top_level_objects(
00188         const sc_simcontext* simc_p);
00189     friend bool sc_is_running( const sc_simcontext* simc_p );
00190 
00191     friend bool sc_end_of_simulation_invoked();
00192     friend bool sc_pending_activity_at_current_time();
00193     friend bool sc_start_of_simulation_invoked();
00194 
00195     void init();
00196     void clean();
00197 
00198 public:
00199 
00200     sc_simcontext();
00201     ~sc_simcontext();
00202 
00203     void initialize( bool = false );
00204     void cycle( const sc_time& );
00205     void simulate( const sc_time& duration );
00206     void stop();
00207     void end();
00208     void reset();
00209 
00210     int sim_status() const;
00211     bool elaboration_done() const;
00212 
00213     sc_object_manager* get_object_manager();
00214 
00215     void hierarchy_push( sc_module* );
00216     sc_module* hierarchy_pop();
00217     sc_module* hierarchy_curr() const;
00218     sc_object* first_object();
00219     sc_object* next_object();
00220     sc_object* find_object( const char* name );
00221 
00222     sc_module_registry* get_module_registry();
00223     sc_port_registry* get_port_registry();
00224     sc_export_registry* get_export_registry();
00225     sc_prim_channel_registry* get_prim_channel_registry();
00226 
00227     // to generate unique names for objects in an MT-Safe way
00228     const char* gen_unique_name( const char* basename_, 
00229                                  bool preserve_first = false 
00230                                );
00231 
00232     // process creation
00233     sc_process_handle create_cthread_process( 
00234     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p, 
00235     sc_process_host* host_p, const sc_spawn_options* opt_p );
00236 
00237     sc_process_handle create_method_process( 
00238     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p, 
00239     sc_process_host* host_p, const sc_spawn_options* opt_p );
00240 
00241     sc_process_handle create_thread_process( 
00242     const char* name_p, bool free_host, SC_ENTRY_FUNC method_p, 
00243     sc_process_host* host_p, const sc_spawn_options* opt_p );
00244 
00245     sc_curr_proc_handle get_curr_proc_info();
00246     sc_object* get_current_writer() const;
00247     bool write_check() const;
00248     void set_curr_proc( sc_process_b* );
00249     void reset_curr_proc();
00250 
00251     int next_proc_id();
00252 
00253     void add_trace_file( sc_trace_file* );
00254 
00255     friend void    sc_set_time_resolution( double, sc_time_unit );
00256     friend sc_time sc_get_time_resolution();
00257     friend void    sc_set_default_time_unit( double, sc_time_unit );
00258     friend sc_time sc_get_default_time_unit();
00259 
00260     const sc_time& time_stamp() const;
00261 
00262     sc_dt::uint64 delta_count() const;
00263     bool event_occurred( sc_dt::uint64 last_change_count ) const;
00264     bool is_running() const;
00265     bool update_phase() const;
00266     bool get_error();
00267     void set_error();
00268 
00269     sc_cor_pkg* cor_pkg()
00270         { return m_cor_pkg; }
00271     sc_cor* next_cor();
00272 
00273     const ::std::vector<sc_object*>& get_child_objects() const;
00274 
00275     void elaborate();
00276     void prepare_to_simulate();
00277     inline void initial_crunch( bool no_crunch );
00278     const sc_time next_time(); 
00279 
00280 private:
00281 
00282     void add_child_object( sc_object* );
00283     void remove_child_object( sc_object* );
00284 
00285     void crunch(bool once=false);
00286 
00287     int add_delta_event( sc_event* );
00288     void remove_delta_event( sc_event* );
00289     void add_timed_event( sc_event_timed* );
00290 
00291     void trace_cycle( bool delta_cycle );
00292 
00293     const ::std::vector<sc_object*>& get_child_objects_internal() const;
00294 
00295     void push_runnable_method( sc_method_handle );
00296     void push_runnable_thread( sc_thread_handle );
00297 
00298     void push_runnable_method_front( sc_method_handle );
00299     void push_runnable_thread_front( sc_thread_handle );
00300 
00301     sc_method_handle pop_runnable_method();
00302     sc_thread_handle pop_runnable_thread();
00303 
00304     void remove_runnable_method( sc_method_handle );
00305     void remove_runnable_thread( sc_thread_handle );
00306 
00307     void do_sc_stop_action();
00308 
00309 private:
00310 
00311     enum execution_phases {
00312         phase_initialize = 0,
00313         phase_evaluate,
00314         phase_update,
00315         phase_notify
00316     };
00317     sc_object_manager*          m_object_manager;
00318 
00319     sc_module_registry*         m_module_registry;
00320     sc_port_registry*           m_port_registry;
00321     sc_export_registry*         m_export_registry;
00322     sc_prim_channel_registry*   m_prim_channel_registry;
00323 
00324     sc_name_gen*                m_name_gen;
00325 
00326     sc_process_table*           m_process_table;
00327     sc_curr_proc_info           m_curr_proc_info;
00328     sc_object*                  m_current_writer;
00329     bool                        m_write_check;
00330     int                         m_next_proc_id;
00331 
00332     std::vector<sc_object*>     m_child_objects;
00333 
00334     std::vector<sc_event*>      m_delta_events;
00335     sc_ppq<sc_event_timed*>*    m_timed_events;
00336 
00337     std::vector<sc_trace_file*> m_trace_files;
00338     bool                        m_something_to_trace;
00339 
00340     sc_runnable*                m_runnable;
00341 
00342     sc_time_params*             m_time_params;
00343     sc_time                     m_curr_time;
00344  
00345     sc_dt::uint64               m_delta_count;
00346     bool                        m_forced_stop;
00347     bool                        m_ready_to_simulate;
00348     bool                        m_elaboration_done;
00349     execution_phases            m_execution_phase;
00350     bool                        m_error;
00351     bool                        m_in_simulator_control;   
00352     bool                        m_end_of_simulation_called;
00353     bool                        m_start_of_simulation_called;
00354 
00355 
00356     sc_event*                   m_until_event;
00357 
00358     sc_cor_pkg*                 m_cor_pkg; // the simcontext's coroutine package
00359     sc_cor*                     m_cor;     // the simcontext's coroutine
00360 
00361 private:
00362 
00363     // disabled
00364     sc_simcontext( const sc_simcontext& );
00365     sc_simcontext& operator = ( const sc_simcontext& );
00366 };
00367 
00368 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00369 
00370 // Not MT safe.
00371 
00372 #if 1
00373 extern sc_simcontext* sc_curr_simcontext;
00374 extern sc_simcontext* sc_default_global_context;
00375 
00376 inline sc_simcontext*
00377 sc_get_curr_simcontext()
00378 {
00379     if( sc_curr_simcontext == 0 ) {
00380         sc_default_global_context = new sc_simcontext;
00381         sc_curr_simcontext = sc_default_global_context;
00382     }
00383     return sc_curr_simcontext;
00384 }
00385 #else
00386     extern sc_simcontext* sc_get_curr_simcontext();
00387 #endif // 0
00388 
00389 
00390 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00391 
00392 inline
00393 bool
00394 sc_simcontext::elaboration_done() const
00395 {
00396     return m_elaboration_done;
00397 }
00398 
00399 
00400 inline
00401 int
00402 sc_simcontext::sim_status() const
00403 {
00404     if( m_error ) {
00405         return SC_SIM_ERROR;
00406     }
00407     if( m_forced_stop ) {
00408         return SC_SIM_USER_STOP;
00409     }
00410     return SC_SIM_OK;
00411 }
00412 
00413 
00414 inline
00415 sc_object_manager*
00416 sc_simcontext::get_object_manager()
00417 {
00418     return m_object_manager;
00419 }
00420 
00421 inline
00422 sc_module_registry*
00423 sc_simcontext::get_module_registry()
00424 {
00425     return m_module_registry;
00426 }
00427 
00428 inline
00429 sc_port_registry*
00430 sc_simcontext::get_port_registry()
00431 {
00432     return m_port_registry;
00433 }
00434 
00435 inline
00436 sc_export_registry*
00437 sc_simcontext::get_export_registry()
00438 {
00439     return m_export_registry;
00440 }
00441 
00442 inline
00443 sc_prim_channel_registry*
00444 sc_simcontext::get_prim_channel_registry()
00445 {
00446     return m_prim_channel_registry;
00447 }
00448 
00449 
00450 inline
00451 sc_curr_proc_handle
00452 sc_simcontext::get_curr_proc_info()
00453 {
00454     return &m_curr_proc_info;
00455 }
00456 
00457 
00458 inline
00459 int
00460 sc_simcontext::next_proc_id()
00461 {
00462     return ( ++ m_next_proc_id );
00463 }
00464 
00465 
00466 inline
00467 const sc_time&
00468 sc_simcontext::time_stamp() const
00469 {
00470     return m_curr_time;
00471 }
00472 
00473 
00474 inline 
00475 bool
00476 sc_simcontext::event_occurred(sc_dt::uint64 last_change_count) const
00477 {
00478     return m_delta_count == last_change_count;
00479 }
00480 
00481 inline
00482 bool
00483 sc_simcontext::update_phase() const
00484 {
00485     return m_execution_phase == phase_update;
00486 }
00487 
00488 inline
00489 void
00490 sc_simcontext::set_error()
00491 {
00492     m_error = true;
00493 }
00494 
00495 
00496 inline
00497 bool
00498 sc_simcontext::get_error()
00499 {
00500     return m_error;
00501 }
00502 
00503 inline
00504 int
00505 sc_simcontext::add_delta_event( sc_event* e )
00506 {
00507     m_delta_events.push_back( e );
00508     return ( m_delta_events.size() - 1 );
00509 }
00510 
00511 inline
00512 void
00513 sc_simcontext::add_timed_event( sc_event_timed* et )
00514 {
00515     m_timed_events->insert( et );
00516 }
00517 
00518 inline sc_object* 
00519 sc_simcontext::get_current_writer() const
00520 {
00521     return m_current_writer;
00522 }
00523 
00524 inline bool 
00525 sc_simcontext::write_check() const
00526 {
00527     return m_write_check;
00528 }
00529 
00530 // ----------------------------------------------------------------------------
00531 
00532 class sc_process_handle;
00533 sc_process_handle sc_get_current_process_handle();
00534 
00535 inline
00536 sc_process_b*
00537 sc_get_current_process_b()
00538 {
00539     return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
00540 }
00541 
00542 // THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
00543 extern sc_process_b* sc_get_curr_process_handle();
00544 
00545 inline
00546 sc_curr_proc_kind
00547 sc_get_curr_process_kind()
00548 {
00549     return sc_get_curr_simcontext()->get_curr_proc_info()->kind;
00550 }
00551 
00552 
00553 inline int sc_get_simulator_status()
00554 {
00555     return sc_get_curr_simcontext()->sim_status();
00556 }
00557 
00558 
00559 // Generates unique names within each module.
00560 extern
00561 const char*
00562 sc_gen_unique_name( const char* basename_, bool preserve_first = false );
00563 
00564 
00565 // Set the random seed for controlled randomization -- not yet implemented
00566 extern
00567 void
00568 sc_set_random_seed( unsigned int seed_ );
00569 
00570 
00571 extern void sc_start();
00572 extern void sc_start( const sc_time& duration );
00573 extern void sc_start( double duration );
00574 extern void sc_stop();
00575 
00576 extern void sc_initialize();
00577 extern void sc_cycle( const sc_time& duration );
00578 
00579 extern const sc_time& sc_time_stamp();  // Current simulation time.
00580 extern double sc_simulation_time();     // Current time in default time units.
00581 
00582 inline
00583 const std::vector<sc_object*>& sc_get_top_level_objects(
00584     const sc_simcontext* simc_p = sc_get_curr_simcontext() )
00585 {
00586     return simc_p->m_child_objects;
00587 }
00588 
00589 extern sc_object* sc_find_object(
00590     const char* name, sc_simcontext* simc_p = sc_get_curr_simcontext() );
00591 
00592 inline
00593 sc_dt::uint64 sc_delta_count()
00594 {
00595     return sc_get_curr_simcontext()->m_delta_count;
00596 }
00597 
00598 inline 
00599 bool sc_is_running( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
00600 {
00601     return simc_p->m_ready_to_simulate;
00602 }
00603 
00604 inline
00605 void
00606 sc_start( double duration, sc_time_unit time_unit )
00607 {
00608     sc_start( sc_time( duration, time_unit ) );
00609 }
00610 
00611 inline
00612 void
00613 sc_cycle( double duration, sc_time_unit time_unit )
00614 {
00615     sc_cycle( sc_time( duration, time_unit ) );
00616 }
00617 
00618 // for backward compatibility with 1.0
00619 inline
00620 void
00621 sc_cycle( double duration )  // in default time units
00622 {
00623     sc_cycle( sc_time( duration, true ) );
00624 }
00625 
00626 inline
00627 bool
00628 sc_end_of_simulation_invoked()
00629 {
00630         return sc_get_curr_simcontext()->m_end_of_simulation_called;
00631 }
00632 
00633 
00634 inline
00635 bool 
00636 sc_start_of_simulation_invoked()
00637 {
00638         return sc_get_curr_simcontext()->m_start_of_simulation_called;
00639 }
00640 
00641 } // namespace sc_core
00642 
00643 #endif

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