blob: 9510c0d3fd0a6e3791bd1663a3a43843666d1587 [file] [log] [blame]
/*****************************************************************************
Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
more contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright ownership.
Accellera licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
*****************************************************************************/
/*****************************************************************************
sc_phase_callback_registry.h -- Definition of the simulation phase callbacks
The most critical functions are defined inline in this file. Only active,
if SC_ENABLE_SIMULATION_PHASE_CALLBACKS[_TRACING] is defined during the
SystemC library build.
Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
CHANGE LOG AT END OF FILE
*****************************************************************************/
#ifndef SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
#define SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS ) \
|| defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
# define SC_HAS_PHASE_CALLBACKS_ 1
#else
# define SC_HAS_PHASE_CALLBACKS_ 0
#endif
#include "sysc/kernel/sc_simcontext.h"
#include "sysc/kernel/sc_object_int.h"
#include "sysc/kernel/sc_status.h"
#include <vector>
namespace sc_core {
class sc_simcontext;
class sc_object;
class sc_phase_callback_registry
{
public:
typedef sc_phase_callback_registry this_type;
typedef sc_object cb_type;
typedef cb_type::phase_cb_mask mask_type;
struct entry
{
cb_type* target;
mask_type mask;
};
friend class sc_simcontext;
friend class sc_object;
private: // interface completely internal
explicit
sc_phase_callback_registry( sc_simcontext& simc );
~sc_phase_callback_registry();
// --- callback forwarders
bool construction_done() const; //< returns false
void elaboration_done() const;
void initialization_done() const;
void start_simulation() const;
void evaluation_done() const;
void update_done() const;
void before_timestep() const;
void simulation_paused() const;
void simulation_stopped() const;
void simulation_done() const;
// --- callback registration and implementation
mask_type register_callback( cb_type&, mask_type mask );
mask_type unregister_callback( cb_type&, mask_type mask );
// generic caller
void do_callback( sc_status ) const;
private:
typedef std::vector<entry> storage_type;
typedef std::vector<cb_type*> single_storage_type;
#if SC_HAS_PHASE_CALLBACKS_
// set and restore simulation status
struct scoped_status
{
scoped_status( sc_status& ref, sc_status s )
: ref_(ref), prev_(ref) { ref_ = s;}
~scoped_status() { ref_ = prev_; }
private:
sc_status& ref_;
sc_status prev_;
}; // scoped_status
mask_type validate_mask( cb_type&, mask_type, bool warn );
private:
sc_simcontext* m_simc;
storage_type m_cb_vec; // all callbacks
#if 0
single_storage_type m_cb_eval_vec; // - eval cb shortcut
#endif
single_storage_type m_cb_update_vec; // - update cb shortcut
single_storage_type m_cb_timestep_vec; // - timestep cb shortcut
#endif // SC_HAS_PHASE_CALLBACKS_
private:
// disabled
sc_phase_callback_registry( const this_type& );
this_type& operator=(const this_type&);
}; // sc_phase_callback_registry
// -------------------- callback implementations --------------------
// (empty, if feature is disabled)
inline bool
sc_phase_callback_registry::construction_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_BEFORE_END_OF_ELABORATION );
#endif
return false;
}
inline void
sc_phase_callback_registry::elaboration_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_END_OF_ELABORATION );
#endif
}
inline void
sc_phase_callback_registry::start_simulation() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_START_OF_SIMULATION );
#endif
}
inline void
sc_phase_callback_registry::initialization_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
scoped_status scope( m_simc->m_simulation_status
, SC_END_OF_INITIALIZATION );
do_callback( SC_END_OF_INITIALIZATION );
#endif
}
inline void
sc_phase_callback_registry::simulation_paused() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_PAUSED );
#endif
}
inline void
sc_phase_callback_registry::simulation_stopped() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_STOPPED );
#endif
}
inline void
sc_phase_callback_registry::simulation_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
do_callback( SC_END_OF_SIMULATION );
#endif
}
// -------------- specialized callback implementations --------------
#if 0
inline void
sc_phase_callback_registry::evaluation_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
if( !m_cb_eval_vec.size() ) return;
typedef single_storage_type::const_iterator it_type;
single_storage_type const & vec = m_cb_eval_vec;
scoped_status scope( m_simc->m_simulation_status
, SC_END_OF_EVALUATION );
for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
(*it)->do_simulation_phase_callback();
#endif
}
#endif
inline void
sc_phase_callback_registry::update_done() const
{
#if SC_HAS_PHASE_CALLBACKS_
if( !m_cb_update_vec.size() ) return;
typedef single_storage_type::const_iterator it_type;
single_storage_type const & vec = m_cb_update_vec;
scoped_status scope( m_simc->m_simulation_status
, SC_END_OF_UPDATE );
for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
(*it)->do_simulation_phase_callback();
#endif
}
inline void
sc_phase_callback_registry::before_timestep() const
{
#if SC_HAS_PHASE_CALLBACKS_
if( !m_cb_timestep_vec.size() ) return;
typedef single_storage_type::const_iterator it_type;
single_storage_type const & vec = m_cb_timestep_vec;
scoped_status scope( m_simc->m_simulation_status
, SC_BEFORE_TIMESTEP );
for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
(*it)->do_simulation_phase_callback();
#endif
}
// ------------------------------------------------------------------
} // namespace sc_core
/*****************************************************************************
MODIFICATION LOG - modifiers, enter your name, affiliation, date and
changes you are making here.
Name, Affiliation, Date:
Description of Modification:
*****************************************************************************/
#endif /* SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_ */
// Taf!