112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de/*****************************************************************************
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de  sc_simcontext.cpp -- Provides a simulation context for use with multiple
2312027Sjungma@eit.uni-kl.de                       simulations.
2412027Sjungma@eit.uni-kl.de
2512027Sjungma@eit.uni-kl.de  Original Author: Stan Y. Liao, Synopsys, Inc.
2612027Sjungma@eit.uni-kl.de                   Martin Janssen, Synopsys, Inc.
2712027Sjungma@eit.uni-kl.de
2812027Sjungma@eit.uni-kl.de  CHANGE LOG AT THE END OF THE FILE
2912027Sjungma@eit.uni-kl.de *****************************************************************************/
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.de#include <algorithm>
3212027Sjungma@eit.uni-kl.de
3312027Sjungma@eit.uni-kl.de#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
3412027Sjungma@eit.uni-kl.de
3512027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cor_fiber.h"
3612027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cor_pthread.h"
3712027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cor_qt.h"
3812027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_event.h"
3912027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_kernel_ids.h"
4012027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_module.h"
4112027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_module_registry.h"
4212027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_name_gen.h"
4312027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_object_manager.h"
4412027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cthread_process.h"
4512027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_method_process.h"
4612027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_thread_process.h"
4712027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_process_handle.h"
4812027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_simcontext.h"
4912027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_simcontext_int.h"
5012027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_reset.h"
5112027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_ver.h"
5212027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_boost.h"
5312027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_spawn.h"
5412027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_phase_callback_registry.h"
5512027Sjungma@eit.uni-kl.de#include "sysc/communication/sc_port.h"
5612027Sjungma@eit.uni-kl.de#include "sysc/communication/sc_export.h"
5712027Sjungma@eit.uni-kl.de#include "sysc/communication/sc_prim_channel.h"
5812027Sjungma@eit.uni-kl.de#include "sysc/tracing/sc_trace.h"
5912027Sjungma@eit.uni-kl.de#include "sysc/utils/sc_mempool.h"
6012027Sjungma@eit.uni-kl.de#include "sysc/utils/sc_list.h"
6112027Sjungma@eit.uni-kl.de#include "sysc/utils/sc_utils_ids.h"
6212027Sjungma@eit.uni-kl.de
6312027Sjungma@eit.uni-kl.de// DEBUGGING MACROS:
6412027Sjungma@eit.uni-kl.de//
6512027Sjungma@eit.uni-kl.de// DEBUG_MSG(NAME,P,MSG)
6612027Sjungma@eit.uni-kl.de//     MSG  = message to print
6712027Sjungma@eit.uni-kl.de//     NAME = name that must match the process for the message to print, or
6812027Sjungma@eit.uni-kl.de//            null if the message should be printed unconditionally.
6912027Sjungma@eit.uni-kl.de//     P    = pointer to process message is for, or NULL in which case the
7012027Sjungma@eit.uni-kl.de//            message will not print.
7112027Sjungma@eit.uni-kl.de#if 0
7212027Sjungma@eit.uni-kl.de#   define DEBUG_NAME ""
7312027Sjungma@eit.uni-kl.de#   define DEBUG_MSG(NAME,P,MSG) \
7412027Sjungma@eit.uni-kl.de    { \
7512027Sjungma@eit.uni-kl.de        if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
7612027Sjungma@eit.uni-kl.de          std::cout << "**** " << sc_time_stamp() << " ("  \
7712027Sjungma@eit.uni-kl.de	            << sc_get_current_process_name() << "): " << MSG \
7812027Sjungma@eit.uni-kl.de		    << " - " << P->name() << std::endl; \
7912027Sjungma@eit.uni-kl.de    }
8012027Sjungma@eit.uni-kl.de#else
8112027Sjungma@eit.uni-kl.de#   define DEBUG_MSG(NAME,P,MSG)
8212027Sjungma@eit.uni-kl.de#endif
8312027Sjungma@eit.uni-kl.de
8412027Sjungma@eit.uni-kl.de#if SC_HAS_PHASE_CALLBACKS_
8512027Sjungma@eit.uni-kl.de#  define SC_DO_PHASE_CALLBACK_( Kind ) \
8612027Sjungma@eit.uni-kl.de    m_phase_cb_registry->Kind()
8712027Sjungma@eit.uni-kl.de#else
8812027Sjungma@eit.uni-kl.de#  define SC_DO_PHASE_CALLBACK_( Kind ) \
8912027Sjungma@eit.uni-kl.de    ((void)0) /* do nothing */
9012027Sjungma@eit.uni-kl.de#endif
9112027Sjungma@eit.uni-kl.de
9212027Sjungma@eit.uni-kl.de#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
9312027Sjungma@eit.uni-kl.de// use callback based tracing
9412027Sjungma@eit.uni-kl.de#  define SC_SIMCONTEXT_TRACING_  0
9512027Sjungma@eit.uni-kl.de#else
9612027Sjungma@eit.uni-kl.de// enable tracing via explicit trace_cycle calls from simulator loop
9712027Sjungma@eit.uni-kl.de#  define SC_SIMCONTEXT_TRACING_  1
9812027Sjungma@eit.uni-kl.de#endif
9912027Sjungma@eit.uni-kl.de
10012027Sjungma@eit.uni-kl.denamespace sc_core {
10112027Sjungma@eit.uni-kl.de
10212027Sjungma@eit.uni-kl.desc_stop_mode stop_mode = SC_STOP_FINISH_DELTA;
10312027Sjungma@eit.uni-kl.de
10412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
10512027Sjungma@eit.uni-kl.de//  CLASS : sc_process_table
10612027Sjungma@eit.uni-kl.de//
10712027Sjungma@eit.uni-kl.de//  Container class that keeps track of all method processes,
10812027Sjungma@eit.uni-kl.de//  (c)thread processes.
10912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
11012027Sjungma@eit.uni-kl.de
11112027Sjungma@eit.uni-kl.declass sc_process_table
11212027Sjungma@eit.uni-kl.de{
11312027Sjungma@eit.uni-kl.de  public:
11412027Sjungma@eit.uni-kl.de
11512027Sjungma@eit.uni-kl.de    sc_process_table();
11612027Sjungma@eit.uni-kl.de    ~sc_process_table();
11712027Sjungma@eit.uni-kl.de    void push_front( sc_method_handle );
11812027Sjungma@eit.uni-kl.de    void push_front( sc_thread_handle );
11912027Sjungma@eit.uni-kl.de    sc_method_handle method_q_head();
12012027Sjungma@eit.uni-kl.de    sc_method_handle remove( sc_method_handle );
12112027Sjungma@eit.uni-kl.de    sc_thread_handle thread_q_head();
12212027Sjungma@eit.uni-kl.de    sc_thread_handle remove( sc_thread_handle );
12312027Sjungma@eit.uni-kl.de
12412027Sjungma@eit.uni-kl.de
12512027Sjungma@eit.uni-kl.de  private:
12612027Sjungma@eit.uni-kl.de
12712027Sjungma@eit.uni-kl.de    sc_method_handle  m_method_q;  // Queue of existing method processes.
12812027Sjungma@eit.uni-kl.de    sc_thread_handle  m_thread_q;  // Queue of existing thread processes.
12912027Sjungma@eit.uni-kl.de};
13012027Sjungma@eit.uni-kl.de
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.de// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
13312027Sjungma@eit.uni-kl.de
13412027Sjungma@eit.uni-kl.desc_process_table::sc_process_table() : m_method_q(0), m_thread_q(0)
13512027Sjungma@eit.uni-kl.de{}
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.desc_process_table::~sc_process_table()
13812027Sjungma@eit.uni-kl.de{
13912027Sjungma@eit.uni-kl.de
14012027Sjungma@eit.uni-kl.de    sc_method_handle  method_next_p;	// Next method to delete.
14112027Sjungma@eit.uni-kl.de    sc_method_handle  method_now_p;	// Method now deleting.
14212027Sjungma@eit.uni-kl.de
14312027Sjungma@eit.uni-kl.de    for( method_now_p = m_method_q; method_now_p; method_now_p = method_next_p )
14412027Sjungma@eit.uni-kl.de    {
14512027Sjungma@eit.uni-kl.de	method_next_p = method_now_p->next_exist();
14612027Sjungma@eit.uni-kl.de	delete method_now_p;
14712027Sjungma@eit.uni-kl.de    }
14812027Sjungma@eit.uni-kl.de
14912027Sjungma@eit.uni-kl.de    if ( m_thread_q )
15012027Sjungma@eit.uni-kl.de    {
15112027Sjungma@eit.uni-kl.de        ::std::cout << ::std::endl
15212027Sjungma@eit.uni-kl.de             << "WATCH OUT!! In sc_process_table destructor. "
15312027Sjungma@eit.uni-kl.de             << "Threads and cthreads are not actually getting deleted here. "
15412027Sjungma@eit.uni-kl.de	     << "Some memory may leak. Look at the comments here in "
15512027Sjungma@eit.uni-kl.de	     << "kernel/sc_simcontext.cpp for more details."
15612027Sjungma@eit.uni-kl.de	     << ::std::endl;
15712027Sjungma@eit.uni-kl.de    }
15812027Sjungma@eit.uni-kl.de
15912027Sjungma@eit.uni-kl.de    // don't delete threads and cthreads. If a (c)thread
16012027Sjungma@eit.uni-kl.de    // has died, then it has already been deleted. Only (c)threads created
16112027Sjungma@eit.uni-kl.de    // before simulation-start are in this table. Due to performance
16212027Sjungma@eit.uni-kl.de    // reasons, we don't look up the dying thread in the process table
16312027Sjungma@eit.uni-kl.de    // and remove it from there. simcontext::reset and ~simcontext invoke this
16412027Sjungma@eit.uni-kl.de    // destructor. At present none of these routines are ever invoked.
16512027Sjungma@eit.uni-kl.de    // We can delete threads and cthreads here if a dying thread figured out
16612027Sjungma@eit.uni-kl.de    // it was created before simulation-start and took itself off the
16712027Sjungma@eit.uni-kl.de    // process_table.
16812027Sjungma@eit.uni-kl.de
16912027Sjungma@eit.uni-kl.de#if 0
17012027Sjungma@eit.uni-kl.de    sc_thread_handle  thread_next_p;	// Next thread to delete.
17112027Sjungma@eit.uni-kl.de    sc_thread_handle  thread_now_p;	// Thread now deleting.
17212027Sjungma@eit.uni-kl.de
17312027Sjungma@eit.uni-kl.de    for( thread_now_p=m_thread_q; thread_now_p; thread_now_p=thread_next_p )
17412027Sjungma@eit.uni-kl.de    {
17512027Sjungma@eit.uni-kl.de	thread_next_p = thread_now_p->next_exist();
17612027Sjungma@eit.uni-kl.de	delete thread_now_p;
17712027Sjungma@eit.uni-kl.de    }
17812027Sjungma@eit.uni-kl.de#endif // 0
17912027Sjungma@eit.uni-kl.de}
18012027Sjungma@eit.uni-kl.de
18112027Sjungma@eit.uni-kl.deinline
18212027Sjungma@eit.uni-kl.desc_method_handle
18312027Sjungma@eit.uni-kl.desc_process_table::method_q_head()
18412027Sjungma@eit.uni-kl.de{
18512027Sjungma@eit.uni-kl.de    return m_method_q;
18612027Sjungma@eit.uni-kl.de}
18712027Sjungma@eit.uni-kl.de
18812027Sjungma@eit.uni-kl.deinline
18912027Sjungma@eit.uni-kl.devoid
19012027Sjungma@eit.uni-kl.desc_process_table::push_front( sc_method_handle handle_ )
19112027Sjungma@eit.uni-kl.de{
19212027Sjungma@eit.uni-kl.de    handle_->set_next_exist(m_method_q);
19312027Sjungma@eit.uni-kl.de    m_method_q = handle_;
19412027Sjungma@eit.uni-kl.de}
19512027Sjungma@eit.uni-kl.de
19612027Sjungma@eit.uni-kl.deinline
19712027Sjungma@eit.uni-kl.devoid
19812027Sjungma@eit.uni-kl.desc_process_table::push_front( sc_thread_handle handle_ )
19912027Sjungma@eit.uni-kl.de{
20012027Sjungma@eit.uni-kl.de    handle_->set_next_exist(m_thread_q);
20112027Sjungma@eit.uni-kl.de    m_thread_q = handle_;
20212027Sjungma@eit.uni-kl.de}
20312027Sjungma@eit.uni-kl.de
20412027Sjungma@eit.uni-kl.desc_method_handle
20512027Sjungma@eit.uni-kl.desc_process_table::remove( sc_method_handle handle_ )
20612027Sjungma@eit.uni-kl.de{
20712027Sjungma@eit.uni-kl.de    sc_method_handle now_p;	// Entry now examining.
20812027Sjungma@eit.uni-kl.de    sc_method_handle prior_p;	// Entry prior to one now examining.
20912027Sjungma@eit.uni-kl.de
21012027Sjungma@eit.uni-kl.de    prior_p = 0;
21112027Sjungma@eit.uni-kl.de    for ( now_p = m_method_q; now_p; now_p = now_p->next_exist() )
21212027Sjungma@eit.uni-kl.de    {
21312027Sjungma@eit.uni-kl.de	if ( now_p == handle_ )
21412027Sjungma@eit.uni-kl.de	{
21512027Sjungma@eit.uni-kl.de	    if ( prior_p )
21612027Sjungma@eit.uni-kl.de		prior_p->set_next_exist( now_p->next_exist() );
21712027Sjungma@eit.uni-kl.de	    else
21812027Sjungma@eit.uni-kl.de		m_method_q = now_p->next_exist();
21912027Sjungma@eit.uni-kl.de	    return handle_;
22012027Sjungma@eit.uni-kl.de	}
22112027Sjungma@eit.uni-kl.de    }
22212027Sjungma@eit.uni-kl.de    return 0;
22312027Sjungma@eit.uni-kl.de}
22412027Sjungma@eit.uni-kl.de
22512027Sjungma@eit.uni-kl.desc_thread_handle
22612027Sjungma@eit.uni-kl.desc_process_table::remove( sc_thread_handle handle_ )
22712027Sjungma@eit.uni-kl.de{
22812027Sjungma@eit.uni-kl.de    sc_thread_handle now_p;	// Entry now examining.
22912027Sjungma@eit.uni-kl.de    sc_thread_handle prior_p;	// Entry prior to one now examining.
23012027Sjungma@eit.uni-kl.de
23112027Sjungma@eit.uni-kl.de    prior_p = 0;
23212027Sjungma@eit.uni-kl.de    for ( now_p = m_thread_q; now_p; now_p = now_p->next_exist() )
23312027Sjungma@eit.uni-kl.de    {
23412027Sjungma@eit.uni-kl.de	if ( now_p == handle_ )
23512027Sjungma@eit.uni-kl.de	{
23612027Sjungma@eit.uni-kl.de	    if ( prior_p )
23712027Sjungma@eit.uni-kl.de		prior_p->set_next_exist( now_p->next_exist() );
23812027Sjungma@eit.uni-kl.de	    else
23912027Sjungma@eit.uni-kl.de		m_thread_q = now_p->next_exist();
24012027Sjungma@eit.uni-kl.de	    return handle_;
24112027Sjungma@eit.uni-kl.de	}
24212027Sjungma@eit.uni-kl.de    }
24312027Sjungma@eit.uni-kl.de    return 0;
24412027Sjungma@eit.uni-kl.de}
24512027Sjungma@eit.uni-kl.de
24612027Sjungma@eit.uni-kl.deinline
24712027Sjungma@eit.uni-kl.desc_thread_handle
24812027Sjungma@eit.uni-kl.desc_process_table::thread_q_head()
24912027Sjungma@eit.uni-kl.de{
25012027Sjungma@eit.uni-kl.de    return m_thread_q;
25112027Sjungma@eit.uni-kl.de}
25212027Sjungma@eit.uni-kl.de
25312027Sjungma@eit.uni-kl.deint
25412027Sjungma@eit.uni-kl.desc_notify_time_compare( const void* p1, const void* p2 )
25512027Sjungma@eit.uni-kl.de{
25612027Sjungma@eit.uni-kl.de    const sc_event_timed* et1 = static_cast<const sc_event_timed*>( p1 );
25712027Sjungma@eit.uni-kl.de    const sc_event_timed* et2 = static_cast<const sc_event_timed*>( p2 );
25812027Sjungma@eit.uni-kl.de
25912027Sjungma@eit.uni-kl.de    const sc_time& t1 = et1->notify_time();
26012027Sjungma@eit.uni-kl.de    const sc_time& t2 = et2->notify_time();
26112027Sjungma@eit.uni-kl.de
26212027Sjungma@eit.uni-kl.de    if( t1 < t2 ) {
26312027Sjungma@eit.uni-kl.de	return 1;
26412027Sjungma@eit.uni-kl.de    } else if( t1 > t2 ) {
26512027Sjungma@eit.uni-kl.de	return -1;
26612027Sjungma@eit.uni-kl.de    } else {
26712027Sjungma@eit.uni-kl.de	return 0;
26812027Sjungma@eit.uni-kl.de    }
26912027Sjungma@eit.uni-kl.de}
27012027Sjungma@eit.uni-kl.de
27112027Sjungma@eit.uni-kl.de
27212027Sjungma@eit.uni-kl.de// +============================================================================
27312027Sjungma@eit.uni-kl.de// | CLASS sc_invoke_method - class to invoke sc_method's to support
27412027Sjungma@eit.uni-kl.de// |                          sc_simcontext::preempt_with().
27512027Sjungma@eit.uni-kl.de// +============================================================================
27612027Sjungma@eit.uni-kl.deSC_MODULE(sc_invoke_method)
27712027Sjungma@eit.uni-kl.de{
27812027Sjungma@eit.uni-kl.de    SC_CTOR(sc_invoke_method)
27912027Sjungma@eit.uni-kl.de    {
28012027Sjungma@eit.uni-kl.de      // remove from object hierarchy
28112027Sjungma@eit.uni-kl.de      detach();
28212027Sjungma@eit.uni-kl.de    }
28312027Sjungma@eit.uni-kl.de
28412027Sjungma@eit.uni-kl.de    virtual ~sc_invoke_method()
28512027Sjungma@eit.uni-kl.de    {
28612027Sjungma@eit.uni-kl.de	m_invokers.resize(0);
28712027Sjungma@eit.uni-kl.de    }
28812027Sjungma@eit.uni-kl.de
28912027Sjungma@eit.uni-kl.de    // Method to call to execute a method's semantics.
29012027Sjungma@eit.uni-kl.de
29112027Sjungma@eit.uni-kl.de    void invoke_method( sc_method_handle method_h )
29212027Sjungma@eit.uni-kl.de    {
29312027Sjungma@eit.uni-kl.de	sc_process_handle invoker_h;  // handle for invocation thread to use.
29412027Sjungma@eit.uni-kl.de	std::vector<sc_process_handle>::size_type invokers_n; // number of invocation threads available.
29512027Sjungma@eit.uni-kl.de
29612027Sjungma@eit.uni-kl.de	m_method = method_h;
29712027Sjungma@eit.uni-kl.de
29812027Sjungma@eit.uni-kl.de	// There is not an invocation thread to use, so allocate one.
29912027Sjungma@eit.uni-kl.de
30012027Sjungma@eit.uni-kl.de	invokers_n = m_invokers.size();
30112027Sjungma@eit.uni-kl.de	if ( invokers_n == 0 )
30212027Sjungma@eit.uni-kl.de	{
30312027Sjungma@eit.uni-kl.de	    sc_spawn_options options;
30412027Sjungma@eit.uni-kl.de	    options.dont_initialize();
30512027Sjungma@eit.uni-kl.de	    options.set_stack_size(0x100000);
30612027Sjungma@eit.uni-kl.de	    options.set_sensitivity(&m_dummy);
30712027Sjungma@eit.uni-kl.de	    invoker_h = sc_spawn(sc_bind(&sc_invoke_method::invoker,this),
30812027Sjungma@eit.uni-kl.de				 sc_gen_unique_name("invoker"), &options);
30912027Sjungma@eit.uni-kl.de	    ((sc_process_b*)invoker_h)->detach();
31012027Sjungma@eit.uni-kl.de	}
31112027Sjungma@eit.uni-kl.de
31212027Sjungma@eit.uni-kl.de	// There is an invocation thread to use, use the last one on the list.
31312027Sjungma@eit.uni-kl.de
31412027Sjungma@eit.uni-kl.de	else
31512027Sjungma@eit.uni-kl.de	{
31612027Sjungma@eit.uni-kl.de	    invoker_h = m_invokers[invokers_n-1];
31712027Sjungma@eit.uni-kl.de	    m_invokers.pop_back();
31812027Sjungma@eit.uni-kl.de	}
31912027Sjungma@eit.uni-kl.de
32012027Sjungma@eit.uni-kl.de	// Fire off the invocation thread to invoke the method's semantics,
32112027Sjungma@eit.uni-kl.de	// When it blocks put it onto the list of invocation threads that
32212027Sjungma@eit.uni-kl.de	// are available.
32312027Sjungma@eit.uni-kl.de
32412027Sjungma@eit.uni-kl.de        sc_get_curr_simcontext()->preempt_with( (sc_thread_handle)invoker_h );
32512027Sjungma@eit.uni-kl.de	DEBUG_MSG( DEBUG_NAME, m_method, "back from preemption" );
32612027Sjungma@eit.uni-kl.de	m_invokers.push_back(invoker_h);
32712027Sjungma@eit.uni-kl.de    }
32812027Sjungma@eit.uni-kl.de
32912027Sjungma@eit.uni-kl.de    // Thread to call method from:
33012027Sjungma@eit.uni-kl.de
33112027Sjungma@eit.uni-kl.de    void invoker()
33212027Sjungma@eit.uni-kl.de    {
33312027Sjungma@eit.uni-kl.de	sc_simcontext* csc_p = sc_get_curr_simcontext();
33412027Sjungma@eit.uni-kl.de	sc_process_b*  me = sc_get_current_process_b();
33512027Sjungma@eit.uni-kl.de
33612027Sjungma@eit.uni-kl.de	DEBUG_MSG( DEBUG_NAME, me, "invoker initialization" );
33712027Sjungma@eit.uni-kl.de        for (;; )
33812027Sjungma@eit.uni-kl.de        {
33912027Sjungma@eit.uni-kl.de            DEBUG_MSG( DEBUG_NAME, m_method, "invoker executing method" );
34012027Sjungma@eit.uni-kl.de	    csc_p->set_curr_proc( (sc_process_b*)m_method );
34112027Sjungma@eit.uni-kl.de	    csc_p->get_active_invokers().push_back((sc_thread_handle)me);
34212027Sjungma@eit.uni-kl.de	    m_method->run_process();
34312027Sjungma@eit.uni-kl.de	    csc_p->set_curr_proc( me );
34412027Sjungma@eit.uni-kl.de	    csc_p->get_active_invokers().pop_back();
34512027Sjungma@eit.uni-kl.de            DEBUG_MSG( DEBUG_NAME, m_method, "back from executing method" );
34612027Sjungma@eit.uni-kl.de	    wait();
34712027Sjungma@eit.uni-kl.de	}
34812027Sjungma@eit.uni-kl.de    }
34912027Sjungma@eit.uni-kl.de
35012027Sjungma@eit.uni-kl.de    sc_event                       m_dummy;    // dummy event to wait on.
35112027Sjungma@eit.uni-kl.de    sc_method_handle               m_method;   // method to be invoked.
35212027Sjungma@eit.uni-kl.de    std::vector<sc_process_handle> m_invokers; // list of invoking threads.
35312027Sjungma@eit.uni-kl.de};
35412027Sjungma@eit.uni-kl.de
35512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
35612027Sjungma@eit.uni-kl.de//  CLASS : sc_simcontext
35712027Sjungma@eit.uni-kl.de//
35812027Sjungma@eit.uni-kl.de//  The simulation context.
35912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
36012027Sjungma@eit.uni-kl.de
36112027Sjungma@eit.uni-kl.devoid
36212027Sjungma@eit.uni-kl.desc_simcontext::init()
36312027Sjungma@eit.uni-kl.de{
36412027Sjungma@eit.uni-kl.de
36512027Sjungma@eit.uni-kl.de    // ALLOCATE VARIOUS MANAGERS AND REGISTRIES:
36612027Sjungma@eit.uni-kl.de
36712027Sjungma@eit.uni-kl.de    m_object_manager = new sc_object_manager;
36812027Sjungma@eit.uni-kl.de    m_module_registry = new sc_module_registry( *this );
36912027Sjungma@eit.uni-kl.de    m_port_registry = new sc_port_registry( *this );
37012027Sjungma@eit.uni-kl.de    m_export_registry = new sc_export_registry( *this );
37112027Sjungma@eit.uni-kl.de    m_prim_channel_registry = new sc_prim_channel_registry( *this );
37212027Sjungma@eit.uni-kl.de    m_phase_cb_registry = new sc_phase_callback_registry( *this );
37312027Sjungma@eit.uni-kl.de    m_name_gen = new sc_name_gen;
37412027Sjungma@eit.uni-kl.de    m_process_table = new sc_process_table;
37512027Sjungma@eit.uni-kl.de    m_current_writer = 0;
37612027Sjungma@eit.uni-kl.de
37712027Sjungma@eit.uni-kl.de
37812027Sjungma@eit.uni-kl.de    // CHECK FOR ENVIRONMENT VARIABLES THAT MODIFY SIMULATOR EXECUTION:
37912027Sjungma@eit.uni-kl.de
38012027Sjungma@eit.uni-kl.de    const char* write_check = std::getenv("SC_SIGNAL_WRITE_CHECK");
38112027Sjungma@eit.uni-kl.de    m_write_check = ( (write_check==0) || strcmp(write_check,"DISABLE") ) ?
38212027Sjungma@eit.uni-kl.de      true : false;
38312027Sjungma@eit.uni-kl.de
38412027Sjungma@eit.uni-kl.de
38512027Sjungma@eit.uni-kl.de    // FINISH INITIALIZATIONS:
38612027Sjungma@eit.uni-kl.de
38712027Sjungma@eit.uni-kl.de    reset_curr_proc();
38812027Sjungma@eit.uni-kl.de    m_next_proc_id = -1;
38912027Sjungma@eit.uni-kl.de    m_timed_events = new sc_ppq<sc_event_timed*>( 128, sc_notify_time_compare );
39012027Sjungma@eit.uni-kl.de    m_something_to_trace = false;
39112027Sjungma@eit.uni-kl.de    m_runnable = new sc_runnable;
39212027Sjungma@eit.uni-kl.de    m_collectable = new sc_process_list;
39312027Sjungma@eit.uni-kl.de    m_time_params = new sc_time_params;
39412027Sjungma@eit.uni-kl.de    m_curr_time = SC_ZERO_TIME;
39512027Sjungma@eit.uni-kl.de    m_max_time = SC_ZERO_TIME;
39612027Sjungma@eit.uni-kl.de    m_change_stamp = 0;
39712027Sjungma@eit.uni-kl.de    m_delta_count = 0;
39812027Sjungma@eit.uni-kl.de    m_forced_stop = false;
39912027Sjungma@eit.uni-kl.de    m_paused = false;
40012027Sjungma@eit.uni-kl.de    m_ready_to_simulate = false;
40112027Sjungma@eit.uni-kl.de    m_elaboration_done = false;
40212027Sjungma@eit.uni-kl.de    m_execution_phase = phase_initialize;
40312027Sjungma@eit.uni-kl.de    m_error = NULL;
40412027Sjungma@eit.uni-kl.de    m_cor_pkg = 0;
40512027Sjungma@eit.uni-kl.de    m_method_invoker_p = NULL;
40612027Sjungma@eit.uni-kl.de    m_cor = 0;
40712027Sjungma@eit.uni-kl.de    m_in_simulator_control = false;
40812027Sjungma@eit.uni-kl.de    m_start_of_simulation_called = false;
40912027Sjungma@eit.uni-kl.de    m_end_of_simulation_called = false;
41012027Sjungma@eit.uni-kl.de    m_simulation_status = SC_ELABORATION;
41112027Sjungma@eit.uni-kl.de}
41212027Sjungma@eit.uni-kl.de
41312027Sjungma@eit.uni-kl.devoid
41412027Sjungma@eit.uni-kl.desc_simcontext::clean()
41512027Sjungma@eit.uni-kl.de{
41612027Sjungma@eit.uni-kl.de    delete m_object_manager;
41712027Sjungma@eit.uni-kl.de    delete m_module_registry;
41812027Sjungma@eit.uni-kl.de    delete m_port_registry;
41912027Sjungma@eit.uni-kl.de    delete m_export_registry;
42012027Sjungma@eit.uni-kl.de    delete m_prim_channel_registry;
42112027Sjungma@eit.uni-kl.de    delete m_phase_cb_registry;
42212027Sjungma@eit.uni-kl.de    delete m_name_gen;
42312027Sjungma@eit.uni-kl.de    delete m_process_table;
42412027Sjungma@eit.uni-kl.de    m_child_objects.resize(0);
42512027Sjungma@eit.uni-kl.de    m_delta_events.resize(0);
42612027Sjungma@eit.uni-kl.de    delete m_timed_events;
42712027Sjungma@eit.uni-kl.de    for( int i = m_trace_files.size() - 1; i >= 0; -- i ) {
42812027Sjungma@eit.uni-kl.de	delete m_trace_files[i];
42912027Sjungma@eit.uni-kl.de    }
43012027Sjungma@eit.uni-kl.de    m_trace_files.resize(0);
43112027Sjungma@eit.uni-kl.de    delete m_runnable;
43212027Sjungma@eit.uni-kl.de    delete m_collectable;
43312027Sjungma@eit.uni-kl.de    delete m_time_params;
43412027Sjungma@eit.uni-kl.de    delete m_cor_pkg;
43512027Sjungma@eit.uni-kl.de    delete m_error;
43612027Sjungma@eit.uni-kl.de}
43712027Sjungma@eit.uni-kl.de
43812027Sjungma@eit.uni-kl.de
43912027Sjungma@eit.uni-kl.desc_simcontext::sc_simcontext() :
44012027Sjungma@eit.uni-kl.de    m_object_manager(0), m_module_registry(0), m_port_registry(0),
44112027Sjungma@eit.uni-kl.de    m_export_registry(0), m_prim_channel_registry(0),
44212027Sjungma@eit.uni-kl.de    m_phase_cb_registry(0), m_name_gen(0),
44312027Sjungma@eit.uni-kl.de    m_process_table(0), m_curr_proc_info(), m_current_writer(0),
44412027Sjungma@eit.uni-kl.de    m_write_check(false), m_next_proc_id(-1), m_child_events(),
44512027Sjungma@eit.uni-kl.de    m_child_objects(), m_delta_events(), m_timed_events(0), m_trace_files(),
44612027Sjungma@eit.uni-kl.de    m_something_to_trace(false), m_runnable(0), m_collectable(0),
44712027Sjungma@eit.uni-kl.de    m_time_params(), m_curr_time(SC_ZERO_TIME), m_max_time(SC_ZERO_TIME),
44812027Sjungma@eit.uni-kl.de    m_change_stamp(0), m_delta_count(0), m_forced_stop(false), m_paused(false),
44912027Sjungma@eit.uni-kl.de    m_ready_to_simulate(false), m_elaboration_done(false),
45012027Sjungma@eit.uni-kl.de    m_execution_phase(phase_initialize), m_error(0),
45112027Sjungma@eit.uni-kl.de    m_in_simulator_control(false), m_end_of_simulation_called(false),
45212027Sjungma@eit.uni-kl.de    m_simulation_status(SC_ELABORATION), m_start_of_simulation_called(false),
45312027Sjungma@eit.uni-kl.de    m_cor_pkg(0), m_cor(0)
45412027Sjungma@eit.uni-kl.de{
45512027Sjungma@eit.uni-kl.de    init();
45612027Sjungma@eit.uni-kl.de}
45712027Sjungma@eit.uni-kl.de
45812027Sjungma@eit.uni-kl.desc_simcontext::~sc_simcontext()
45912027Sjungma@eit.uni-kl.de{
46012027Sjungma@eit.uni-kl.de    clean();
46112027Sjungma@eit.uni-kl.de}
46212027Sjungma@eit.uni-kl.de
46312027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
46412027Sjungma@eit.uni-kl.de// |"sc_simcontext::active_object"
46512027Sjungma@eit.uni-kl.de// |
46612027Sjungma@eit.uni-kl.de// | This method returns the currently active object with respect to
46712027Sjungma@eit.uni-kl.de// | additions to the hierarchy. It will be the top of the object hierarchy
46812027Sjungma@eit.uni-kl.de// | stack if it is non-empty, or it will be the active process, or NULL
46912027Sjungma@eit.uni-kl.de// | if there is no active process.
47012027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
47112027Sjungma@eit.uni-kl.desc_object*
47212027Sjungma@eit.uni-kl.desc_simcontext::active_object()
47312027Sjungma@eit.uni-kl.de{
47412027Sjungma@eit.uni-kl.de    sc_object* result_p; // pointer to return.
47512027Sjungma@eit.uni-kl.de
47612027Sjungma@eit.uni-kl.de    result_p = m_object_manager->hierarchy_curr();
47712027Sjungma@eit.uni-kl.de    if ( !result_p )
47812027Sjungma@eit.uni-kl.de        result_p = (sc_object*)get_curr_proc_info()->process_handle;
47912027Sjungma@eit.uni-kl.de    return result_p;
48012027Sjungma@eit.uni-kl.de}
48112027Sjungma@eit.uni-kl.de
48212027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
48312027Sjungma@eit.uni-kl.de// |"sc_simcontext::crunch"
48412027Sjungma@eit.uni-kl.de// |
48512027Sjungma@eit.uni-kl.de// | This method implements the simulator's execution of processes. It performs
48612027Sjungma@eit.uni-kl.de// | one or more "delta" cycles. Each delta cycle consists of an evaluation,
48712027Sjungma@eit.uni-kl.de// | an update phase, and a notification phase. During the evaluation phase any
48812027Sjungma@eit.uni-kl.de// | processes that are ready to run are executed. After all the processes have
48912027Sjungma@eit.uni-kl.de// | been executed the update phase is entered. During the update phase the
49012027Sjungma@eit.uni-kl.de// | values of any signals that have changed are updated. After the updates
49112027Sjungma@eit.uni-kl.de// | have been performed the notification phase is entered. During that phase
49212027Sjungma@eit.uni-kl.de// | any notifications that need to occur because of of signal values changes
49312027Sjungma@eit.uni-kl.de// | are performed. This will result in the queueing of processes for execution
49412027Sjungma@eit.uni-kl.de// | that are sensitive to those notifications. At that point a delta cycle
49512027Sjungma@eit.uni-kl.de// | is complete, and the process is started again unless 'once' is true.
49612027Sjungma@eit.uni-kl.de// |
49712027Sjungma@eit.uni-kl.de// | Arguments:
49812027Sjungma@eit.uni-kl.de// |     once = true if only one delta cycle is to be performed.
49912027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
50012027Sjungma@eit.uni-kl.deinline void
50112027Sjungma@eit.uni-kl.desc_simcontext::crunch( bool once )
50212027Sjungma@eit.uni-kl.de{
50312027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
50412027Sjungma@eit.uni-kl.de    int num_deltas = 0;  // number of delta cycles
50512027Sjungma@eit.uni-kl.de#endif
50612027Sjungma@eit.uni-kl.de
50712027Sjungma@eit.uni-kl.de    while ( true )
50812027Sjungma@eit.uni-kl.de    {
50912027Sjungma@eit.uni-kl.de
51012027Sjungma@eit.uni-kl.de	// EVALUATE PHASE
51112027Sjungma@eit.uni-kl.de
51212027Sjungma@eit.uni-kl.de	m_execution_phase = phase_evaluate;
51312027Sjungma@eit.uni-kl.de	bool empty_eval_phase = true;
51412027Sjungma@eit.uni-kl.de	while( true )
51512027Sjungma@eit.uni-kl.de	{
51612027Sjungma@eit.uni-kl.de
51712027Sjungma@eit.uni-kl.de	    // execute method processes
51812027Sjungma@eit.uni-kl.de
51912027Sjungma@eit.uni-kl.de	    m_runnable->toggle_methods();
52012027Sjungma@eit.uni-kl.de	    sc_method_handle method_h = pop_runnable_method();
52112027Sjungma@eit.uni-kl.de	    while( method_h != 0 ) {
52212027Sjungma@eit.uni-kl.de		empty_eval_phase = false;
52312027Sjungma@eit.uni-kl.de		if ( !method_h->run_process() )
52412027Sjungma@eit.uni-kl.de		{
52512027Sjungma@eit.uni-kl.de		    goto out;
52612027Sjungma@eit.uni-kl.de		}
52712027Sjungma@eit.uni-kl.de		method_h = pop_runnable_method();
52812027Sjungma@eit.uni-kl.de	    }
52912027Sjungma@eit.uni-kl.de
53012027Sjungma@eit.uni-kl.de	    // execute (c)thread processes
53112027Sjungma@eit.uni-kl.de
53212027Sjungma@eit.uni-kl.de	    m_runnable->toggle_threads();
53312027Sjungma@eit.uni-kl.de	    sc_thread_handle thread_h = pop_runnable_thread();
53412027Sjungma@eit.uni-kl.de	    while( thread_h != 0 ) {
53512027Sjungma@eit.uni-kl.de                if ( thread_h->m_cor_p != NULL ) break;
53612027Sjungma@eit.uni-kl.de		thread_h = pop_runnable_thread();
53712027Sjungma@eit.uni-kl.de	    }
53812027Sjungma@eit.uni-kl.de
53912027Sjungma@eit.uni-kl.de	    if( thread_h != 0 ) {
54012027Sjungma@eit.uni-kl.de	        empty_eval_phase = false;
54112027Sjungma@eit.uni-kl.de		m_cor_pkg->yield( thread_h->m_cor_p );
54212027Sjungma@eit.uni-kl.de	    }
54312027Sjungma@eit.uni-kl.de	    if( m_error ) {
54412027Sjungma@eit.uni-kl.de		goto out;
54512027Sjungma@eit.uni-kl.de	    }
54612027Sjungma@eit.uni-kl.de
54712027Sjungma@eit.uni-kl.de	    // check for call(s) to sc_stop
54812027Sjungma@eit.uni-kl.de	    if( m_forced_stop ) {
54912027Sjungma@eit.uni-kl.de		if ( stop_mode == SC_STOP_IMMEDIATE ) goto out;
55012027Sjungma@eit.uni-kl.de	    }
55112027Sjungma@eit.uni-kl.de
55212027Sjungma@eit.uni-kl.de	    // no more runnable processes
55312027Sjungma@eit.uni-kl.de
55412027Sjungma@eit.uni-kl.de	    if( m_runnable->is_empty() ) {
55512027Sjungma@eit.uni-kl.de		break;
55612027Sjungma@eit.uni-kl.de	    }
55712027Sjungma@eit.uni-kl.de	}
55812027Sjungma@eit.uni-kl.de
55912027Sjungma@eit.uni-kl.de	// remove finally dead zombies:
56012027Sjungma@eit.uni-kl.de
56112027Sjungma@eit.uni-kl.de        while( ! m_collectable->empty() )
56212027Sjungma@eit.uni-kl.de        {
56312027Sjungma@eit.uni-kl.de	    sc_process_b* del_p = m_collectable->front();
56412027Sjungma@eit.uni-kl.de	    m_collectable->pop_front();
56512027Sjungma@eit.uni-kl.de	    del_p->reference_decrement();
56612027Sjungma@eit.uni-kl.de        }
56712027Sjungma@eit.uni-kl.de
56812027Sjungma@eit.uni-kl.de
56912027Sjungma@eit.uni-kl.de	// UPDATE PHASE
57012027Sjungma@eit.uni-kl.de	//
57112027Sjungma@eit.uni-kl.de	// The change stamp must be updated first so that event_occurred()
57212027Sjungma@eit.uni-kl.de	// will work.
57312027Sjungma@eit.uni-kl.de
57412027Sjungma@eit.uni-kl.de	m_execution_phase = phase_update;
57512027Sjungma@eit.uni-kl.de	if ( !empty_eval_phase )
57612027Sjungma@eit.uni-kl.de	{
57712027Sjungma@eit.uni-kl.de//	    SC_DO_PHASE_CALLBACK_(evaluation_done);
57812027Sjungma@eit.uni-kl.de	    m_change_stamp++;
57912027Sjungma@eit.uni-kl.de	    m_delta_count ++;
58012027Sjungma@eit.uni-kl.de	}
58112027Sjungma@eit.uni-kl.de	m_prim_channel_registry->perform_update();
58212027Sjungma@eit.uni-kl.de	SC_DO_PHASE_CALLBACK_(update_done);
58312027Sjungma@eit.uni-kl.de	m_execution_phase = phase_notify;
58412027Sjungma@eit.uni-kl.de
58512027Sjungma@eit.uni-kl.de#if SC_SIMCONTEXT_TRACING_
58612027Sjungma@eit.uni-kl.de	if( m_something_to_trace ) {
58712027Sjungma@eit.uni-kl.de	    trace_cycle( /* delta cycle? */ true );
58812027Sjungma@eit.uni-kl.de	}
58912027Sjungma@eit.uni-kl.de#endif
59012027Sjungma@eit.uni-kl.de
59112027Sjungma@eit.uni-kl.de        // check for call(s) to sc_stop
59212027Sjungma@eit.uni-kl.de        if( m_forced_stop ) {
59312027Sjungma@eit.uni-kl.de            break;
59412027Sjungma@eit.uni-kl.de        }
59512027Sjungma@eit.uni-kl.de
59612027Sjungma@eit.uni-kl.de#ifdef DEBUG_SYSTEMC
59712027Sjungma@eit.uni-kl.de        // check for possible infinite loops
59812027Sjungma@eit.uni-kl.de        if( ++ num_deltas > SC_MAX_NUM_DELTA_CYCLES ) {
59912027Sjungma@eit.uni-kl.de	    ::std::cerr << "SystemC warning: "
60012027Sjungma@eit.uni-kl.de		 << "the number of delta cycles exceeds the limit of "
60112027Sjungma@eit.uni-kl.de		 << SC_MAX_NUM_DELTA_CYCLES
60212027Sjungma@eit.uni-kl.de		 << ", defined in sc_constants.h.\n"
60312027Sjungma@eit.uni-kl.de		 << "This is a possible sign of an infinite loop.\n"
60412027Sjungma@eit.uni-kl.de		 << "Increase the limit if this warning is invalid.\n";
60512027Sjungma@eit.uni-kl.de	    break;
60612027Sjungma@eit.uni-kl.de	}
60712027Sjungma@eit.uni-kl.de#endif
60812027Sjungma@eit.uni-kl.de
60912027Sjungma@eit.uni-kl.de	// NOTIFICATION PHASE:
61012027Sjungma@eit.uni-kl.de	//
61112027Sjungma@eit.uni-kl.de	// Process delta notifications which will queue processes for
61212027Sjungma@eit.uni-kl.de	// subsequent execution.
61312027Sjungma@eit.uni-kl.de
61412027Sjungma@eit.uni-kl.de        int size = m_delta_events.size();
61512027Sjungma@eit.uni-kl.de	if ( size != 0 )
61612027Sjungma@eit.uni-kl.de	{
61712027Sjungma@eit.uni-kl.de	    sc_event** l_events = &m_delta_events[0];
61812027Sjungma@eit.uni-kl.de	    int i = size - 1;
61912027Sjungma@eit.uni-kl.de	    do {
62012027Sjungma@eit.uni-kl.de		l_events[i]->trigger();
62112027Sjungma@eit.uni-kl.de	    } while( -- i >= 0 );
62212027Sjungma@eit.uni-kl.de	    m_delta_events.resize(0);
62312027Sjungma@eit.uni-kl.de	}
62412027Sjungma@eit.uni-kl.de
62512027Sjungma@eit.uni-kl.de	if( m_runnable->is_empty() ) {
62612027Sjungma@eit.uni-kl.de	    // no more runnable processes
62712027Sjungma@eit.uni-kl.de	    break;
62812027Sjungma@eit.uni-kl.de	}
62912027Sjungma@eit.uni-kl.de
63012027Sjungma@eit.uni-kl.de	// if sc_pause() was called we are done.
63112027Sjungma@eit.uni-kl.de
63212027Sjungma@eit.uni-kl.de	if ( m_paused ) break;
63312027Sjungma@eit.uni-kl.de
63412027Sjungma@eit.uni-kl.de        // IF ONLY DOING ONE CYCLE, WE ARE DONE. OTHERWISE EXECUTE NEW CALLBACKS
63512027Sjungma@eit.uni-kl.de
63612027Sjungma@eit.uni-kl.de        if ( once ) break;
63712027Sjungma@eit.uni-kl.de    }
63812027Sjungma@eit.uni-kl.de
63912027Sjungma@eit.uni-kl.de    // When this point is reached the processing of delta cycles is complete,
64012027Sjungma@eit.uni-kl.de    // if the completion was because of an error throw the exception specified
64112027Sjungma@eit.uni-kl.de    // by '*m_error'.
64212027Sjungma@eit.uni-kl.deout:
64312027Sjungma@eit.uni-kl.de    this->reset_curr_proc();
64412027Sjungma@eit.uni-kl.de    if( m_error ) throw *m_error; // re-throw propagated error
64512027Sjungma@eit.uni-kl.de}
64612027Sjungma@eit.uni-kl.de
64712027Sjungma@eit.uni-kl.deinline
64812027Sjungma@eit.uni-kl.devoid
64912027Sjungma@eit.uni-kl.desc_simcontext::cycle( const sc_time& t)
65012027Sjungma@eit.uni-kl.de{
65112027Sjungma@eit.uni-kl.de    sc_time next_event_time;
65212027Sjungma@eit.uni-kl.de
65312027Sjungma@eit.uni-kl.de    m_in_simulator_control = true;
65412027Sjungma@eit.uni-kl.de    crunch();
65512027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(before_timestep);
65612027Sjungma@eit.uni-kl.de#if SC_SIMCONTEXT_TRACING_
65712027Sjungma@eit.uni-kl.de    if( m_something_to_trace ) {
65812027Sjungma@eit.uni-kl.de        trace_cycle( /* delta cycle? */ false );
65912027Sjungma@eit.uni-kl.de    }
66012027Sjungma@eit.uni-kl.de#endif
66112027Sjungma@eit.uni-kl.de    m_curr_time += t;
66212027Sjungma@eit.uni-kl.de    if ( next_time(next_event_time) && next_event_time <= m_curr_time) {
66312027Sjungma@eit.uni-kl.de        SC_REPORT_WARNING(SC_ID_CYCLE_MISSES_EVENTS_, "");
66412027Sjungma@eit.uni-kl.de    }
66512027Sjungma@eit.uni-kl.de    m_in_simulator_control = false;
66612027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(simulation_paused);
66712027Sjungma@eit.uni-kl.de}
66812027Sjungma@eit.uni-kl.de
66912027Sjungma@eit.uni-kl.devoid
67012027Sjungma@eit.uni-kl.desc_simcontext::elaborate()
67112027Sjungma@eit.uni-kl.de{
67212027Sjungma@eit.uni-kl.de    if( m_elaboration_done || sim_status() != SC_SIM_OK ) {
67312027Sjungma@eit.uni-kl.de        return;
67412027Sjungma@eit.uni-kl.de    }
67512027Sjungma@eit.uni-kl.de
67612027Sjungma@eit.uni-kl.de    // Instantiate the method invocation module
67712027Sjungma@eit.uni-kl.de    // (not added to public object hierarchy)
67812027Sjungma@eit.uni-kl.de
67912027Sjungma@eit.uni-kl.de    m_method_invoker_p =
68012027Sjungma@eit.uni-kl.de      new sc_invoke_method("$$$$kernel_module$$$$_invoke_method" );
68112027Sjungma@eit.uni-kl.de
68212027Sjungma@eit.uni-kl.de    m_simulation_status = SC_BEFORE_END_OF_ELABORATION;
68312027Sjungma@eit.uni-kl.de    for( int cd = 0; cd != 4; /* empty */ )
68412027Sjungma@eit.uni-kl.de    {
68512027Sjungma@eit.uni-kl.de        cd  = m_port_registry->construction_done();
68612027Sjungma@eit.uni-kl.de        cd += m_export_registry->construction_done();
68712027Sjungma@eit.uni-kl.de        cd += m_prim_channel_registry->construction_done();
68812027Sjungma@eit.uni-kl.de        cd += m_module_registry->construction_done();
68912027Sjungma@eit.uni-kl.de
69012027Sjungma@eit.uni-kl.de        // check for call(s) to sc_stop
69112027Sjungma@eit.uni-kl.de        if( m_forced_stop ) {
69212027Sjungma@eit.uni-kl.de            do_sc_stop_action();
69312027Sjungma@eit.uni-kl.de            return;
69412027Sjungma@eit.uni-kl.de        }
69512027Sjungma@eit.uni-kl.de
69612027Sjungma@eit.uni-kl.de    }
69712027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(construction_done);
69812027Sjungma@eit.uni-kl.de
69912027Sjungma@eit.uni-kl.de    // SIGNAL THAT ELABORATION IS DONE
70012027Sjungma@eit.uni-kl.de    //
70112027Sjungma@eit.uni-kl.de    // We set the switch before the calls in case someone creates a process
70212027Sjungma@eit.uni-kl.de    // in an end_of_elaboration callback. We need the information to flag
70312027Sjungma@eit.uni-kl.de    // the process as being dynamic.
70412027Sjungma@eit.uni-kl.de
70512027Sjungma@eit.uni-kl.de    m_elaboration_done = true;
70612027Sjungma@eit.uni-kl.de    m_simulation_status = SC_END_OF_ELABORATION;
70712027Sjungma@eit.uni-kl.de
70812027Sjungma@eit.uni-kl.de    m_port_registry->elaboration_done();
70912027Sjungma@eit.uni-kl.de    m_export_registry->elaboration_done();
71012027Sjungma@eit.uni-kl.de    m_prim_channel_registry->elaboration_done();
71112027Sjungma@eit.uni-kl.de    m_module_registry->elaboration_done();
71212027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(elaboration_done);
71312027Sjungma@eit.uni-kl.de    sc_reset::reconcile_resets();
71412027Sjungma@eit.uni-kl.de
71512027Sjungma@eit.uni-kl.de    // check for call(s) to sc_stop
71612027Sjungma@eit.uni-kl.de    if( m_forced_stop ) {
71712027Sjungma@eit.uni-kl.de        do_sc_stop_action();
71812027Sjungma@eit.uni-kl.de        return;
71912027Sjungma@eit.uni-kl.de    }
72012027Sjungma@eit.uni-kl.de}
72112027Sjungma@eit.uni-kl.de
72212027Sjungma@eit.uni-kl.devoid
72312027Sjungma@eit.uni-kl.desc_simcontext::prepare_to_simulate()
72412027Sjungma@eit.uni-kl.de{
72512027Sjungma@eit.uni-kl.de    sc_method_handle  method_p;  // Pointer to method process accessing.
72612027Sjungma@eit.uni-kl.de    sc_thread_handle  thread_p;  // Pointer to thread process accessing.
72712027Sjungma@eit.uni-kl.de
72812027Sjungma@eit.uni-kl.de    if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) {
72912027Sjungma@eit.uni-kl.de        return;
73012027Sjungma@eit.uni-kl.de    }
73112027Sjungma@eit.uni-kl.de
73212027Sjungma@eit.uni-kl.de    // instantiate the coroutine package
73312027Sjungma@eit.uni-kl.de    m_cor_pkg = new sc_cor_pkg_t( this );
73412027Sjungma@eit.uni-kl.de    m_cor = m_cor_pkg->get_main();
73512027Sjungma@eit.uni-kl.de
73612027Sjungma@eit.uni-kl.de    // NOTIFY ALL OBJECTS THAT SIMULATION IS ABOUT TO START:
73712027Sjungma@eit.uni-kl.de
73812027Sjungma@eit.uni-kl.de    m_simulation_status = SC_START_OF_SIMULATION;
73912027Sjungma@eit.uni-kl.de    m_port_registry->start_simulation();
74012027Sjungma@eit.uni-kl.de    m_export_registry->start_simulation();
74112027Sjungma@eit.uni-kl.de    m_prim_channel_registry->start_simulation();
74212027Sjungma@eit.uni-kl.de    m_module_registry->start_simulation();
74312027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(start_simulation);
74412027Sjungma@eit.uni-kl.de    m_start_of_simulation_called = true;
74512027Sjungma@eit.uni-kl.de
74612027Sjungma@eit.uni-kl.de    // CHECK FOR CALL(S) TO sc_stop
74712027Sjungma@eit.uni-kl.de
74812027Sjungma@eit.uni-kl.de    if( m_forced_stop ) {
74912027Sjungma@eit.uni-kl.de        do_sc_stop_action();
75012027Sjungma@eit.uni-kl.de        return;
75112027Sjungma@eit.uni-kl.de    }
75212027Sjungma@eit.uni-kl.de
75312027Sjungma@eit.uni-kl.de    // PREPARE ALL (C)THREAD PROCESSES FOR SIMULATION:
75412027Sjungma@eit.uni-kl.de
75512027Sjungma@eit.uni-kl.de    for ( thread_p = m_process_table->thread_q_head();
75612027Sjungma@eit.uni-kl.de	  thread_p; thread_p = thread_p->next_exist() )
75712027Sjungma@eit.uni-kl.de    {
75812027Sjungma@eit.uni-kl.de	thread_p->prepare_for_simulation();
75912027Sjungma@eit.uni-kl.de    }
76012027Sjungma@eit.uni-kl.de
76112027Sjungma@eit.uni-kl.de    m_simulation_status = SC_RUNNING;
76212027Sjungma@eit.uni-kl.de    m_ready_to_simulate = true;
76312027Sjungma@eit.uni-kl.de    m_runnable->init();
76412027Sjungma@eit.uni-kl.de
76512027Sjungma@eit.uni-kl.de    // update phase
76612027Sjungma@eit.uni-kl.de
76712027Sjungma@eit.uni-kl.de    m_execution_phase = phase_update;
76812027Sjungma@eit.uni-kl.de    m_prim_channel_registry->perform_update();
76912027Sjungma@eit.uni-kl.de    m_execution_phase = phase_notify;
77012027Sjungma@eit.uni-kl.de
77112027Sjungma@eit.uni-kl.de    int size;
77212027Sjungma@eit.uni-kl.de
77312027Sjungma@eit.uni-kl.de    // make all method processes runnable
77412027Sjungma@eit.uni-kl.de
77512027Sjungma@eit.uni-kl.de    for ( method_p = m_process_table->method_q_head();
77612027Sjungma@eit.uni-kl.de	  method_p; method_p = method_p->next_exist() )
77712027Sjungma@eit.uni-kl.de    {
77812027Sjungma@eit.uni-kl.de	if ( ((method_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
77912027Sjungma@eit.uni-kl.de	     method_p->dont_initialize() )
78012027Sjungma@eit.uni-kl.de	{
78112027Sjungma@eit.uni-kl.de	    if ( method_p->m_static_events.size() == 0 )
78212027Sjungma@eit.uni-kl.de	    {
78312027Sjungma@eit.uni-kl.de	        SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
78412027Sjungma@eit.uni-kl.de		                   method_p->name() );
78512027Sjungma@eit.uni-kl.de	    }
78612027Sjungma@eit.uni-kl.de	}
78712027Sjungma@eit.uni-kl.de	else if ( (method_p->m_state & sc_process_b::ps_bit_suspended) == 0)
78812027Sjungma@eit.uni-kl.de	{
78912027Sjungma@eit.uni-kl.de	    push_runnable_method_front( method_p );
79012027Sjungma@eit.uni-kl.de        }
79112027Sjungma@eit.uni-kl.de	else
79212027Sjungma@eit.uni-kl.de	{
79312027Sjungma@eit.uni-kl.de	    method_p->m_state |= sc_process_b::ps_bit_ready_to_run;
79412027Sjungma@eit.uni-kl.de	}
79512027Sjungma@eit.uni-kl.de    }
79612027Sjungma@eit.uni-kl.de
79712027Sjungma@eit.uni-kl.de    // make thread processes runnable
79812027Sjungma@eit.uni-kl.de    // (cthread processes always have the dont_initialize flag set)
79912027Sjungma@eit.uni-kl.de
80012027Sjungma@eit.uni-kl.de    for ( thread_p = m_process_table->thread_q_head();
80112027Sjungma@eit.uni-kl.de	  thread_p; thread_p = thread_p->next_exist() )
80212027Sjungma@eit.uni-kl.de    {
80312027Sjungma@eit.uni-kl.de	if ( ((thread_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
80412027Sjungma@eit.uni-kl.de	     thread_p->dont_initialize() )
80512027Sjungma@eit.uni-kl.de	{
80612027Sjungma@eit.uni-kl.de	    if ( thread_p->m_static_events.size() == 0 )
80712027Sjungma@eit.uni-kl.de	    {
80812027Sjungma@eit.uni-kl.de	        SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
80912027Sjungma@eit.uni-kl.de		                   thread_p->name() );
81012027Sjungma@eit.uni-kl.de	    }
81112027Sjungma@eit.uni-kl.de	}
81212027Sjungma@eit.uni-kl.de	else if ( (thread_p->m_state & sc_process_b::ps_bit_suspended) == 0)
81312027Sjungma@eit.uni-kl.de	{
81412027Sjungma@eit.uni-kl.de            push_runnable_thread_front( thread_p );
81512027Sjungma@eit.uni-kl.de        }
81612027Sjungma@eit.uni-kl.de	else
81712027Sjungma@eit.uni-kl.de	{
81812027Sjungma@eit.uni-kl.de	    thread_p->m_state |= sc_process_b::ps_bit_ready_to_run;
81912027Sjungma@eit.uni-kl.de	}
82012027Sjungma@eit.uni-kl.de    }
82112027Sjungma@eit.uni-kl.de
82212027Sjungma@eit.uni-kl.de
82312027Sjungma@eit.uni-kl.de    // process delta notifications
82412027Sjungma@eit.uni-kl.de
82512027Sjungma@eit.uni-kl.de    if( ( size = m_delta_events.size() ) != 0 ) {
82612027Sjungma@eit.uni-kl.de        sc_event** l_delta_events = &m_delta_events[0];
82712027Sjungma@eit.uni-kl.de        int i = size - 1;
82812027Sjungma@eit.uni-kl.de        do {
82912027Sjungma@eit.uni-kl.de            l_delta_events[i]->trigger();
83012027Sjungma@eit.uni-kl.de        } while( -- i >= 0 );
83112027Sjungma@eit.uni-kl.de        m_delta_events.resize(0);
83212027Sjungma@eit.uni-kl.de    }
83312027Sjungma@eit.uni-kl.de
83412027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(initialization_done);
83512027Sjungma@eit.uni-kl.de}
83612027Sjungma@eit.uni-kl.de
83712027Sjungma@eit.uni-kl.devoid
83812027Sjungma@eit.uni-kl.desc_simcontext::initial_crunch( bool no_crunch )
83912027Sjungma@eit.uni-kl.de{
84012027Sjungma@eit.uni-kl.de    if( no_crunch || m_runnable->is_empty() ) {
84112027Sjungma@eit.uni-kl.de        return;
84212027Sjungma@eit.uni-kl.de    }
84312027Sjungma@eit.uni-kl.de
84412027Sjungma@eit.uni-kl.de    // run the delta cycle loop
84512027Sjungma@eit.uni-kl.de
84612027Sjungma@eit.uni-kl.de    crunch();
84712027Sjungma@eit.uni-kl.de    if( m_error ) {
84812027Sjungma@eit.uni-kl.de        return;
84912027Sjungma@eit.uni-kl.de    }
85012027Sjungma@eit.uni-kl.de
85112027Sjungma@eit.uni-kl.de#if SC_SIMCONTEXT_TRACING_
85212027Sjungma@eit.uni-kl.de    if( m_something_to_trace ) {
85312027Sjungma@eit.uni-kl.de        trace_cycle( false );
85412027Sjungma@eit.uni-kl.de    }
85512027Sjungma@eit.uni-kl.de#endif
85612027Sjungma@eit.uni-kl.de
85712027Sjungma@eit.uni-kl.de    // check for call(s) to sc_stop
85812027Sjungma@eit.uni-kl.de    if( m_forced_stop ) {
85912027Sjungma@eit.uni-kl.de        do_sc_stop_action();
86012027Sjungma@eit.uni-kl.de    }
86112027Sjungma@eit.uni-kl.de}
86212027Sjungma@eit.uni-kl.de
86312027Sjungma@eit.uni-kl.devoid
86412027Sjungma@eit.uni-kl.desc_simcontext::initialize( bool no_crunch )
86512027Sjungma@eit.uni-kl.de{
86612027Sjungma@eit.uni-kl.de    m_in_simulator_control = true;
86712027Sjungma@eit.uni-kl.de    elaborate();
86812027Sjungma@eit.uni-kl.de
86912027Sjungma@eit.uni-kl.de    prepare_to_simulate();
87012027Sjungma@eit.uni-kl.de    initial_crunch(no_crunch);
87112027Sjungma@eit.uni-kl.de    m_in_simulator_control = false;
87212027Sjungma@eit.uni-kl.de}
87312027Sjungma@eit.uni-kl.de
87412027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
87512027Sjungma@eit.uni-kl.de// |"sc_simcontext::simulate"
87612027Sjungma@eit.uni-kl.de// |
87712027Sjungma@eit.uni-kl.de// | This method runs the simulation for the specified amount of time.
87812027Sjungma@eit.uni-kl.de// |
87912027Sjungma@eit.uni-kl.de// | Notes:
88012027Sjungma@eit.uni-kl.de// |   (1) This code always run with an SC_EXIT_ON_STARVATION starvation policy,
88112027Sjungma@eit.uni-kl.de// |       so the simulation time on return will be the minimum of the
88212027Sjungma@eit.uni-kl.de// |       simulation on entry plus the duration, and the maximum time of any
88312027Sjungma@eit.uni-kl.de// |       event present in the simulation. If the simulation policy is
88412027Sjungma@eit.uni-kl.de// |       SC_RUN_TO_TIME starvation it is implemented by the caller of this
88512027Sjungma@eit.uni-kl.de// |       method, e.g., sc_start(), by artificially setting the simulation
88612027Sjungma@eit.uni-kl.de// |       time forward after this method completes.
88712027Sjungma@eit.uni-kl.de// |
88812027Sjungma@eit.uni-kl.de// | Arguments:
88912027Sjungma@eit.uni-kl.de// |     duration = amount of time to simulate.
89012027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
89112027Sjungma@eit.uni-kl.devoid
89212027Sjungma@eit.uni-kl.desc_simcontext::simulate( const sc_time& duration )
89312027Sjungma@eit.uni-kl.de{
89412027Sjungma@eit.uni-kl.de    initialize( true );
89512027Sjungma@eit.uni-kl.de
89612027Sjungma@eit.uni-kl.de    if (sim_status() != SC_SIM_OK) {
89712027Sjungma@eit.uni-kl.de	return;
89812027Sjungma@eit.uni-kl.de    }
89912027Sjungma@eit.uni-kl.de
90012027Sjungma@eit.uni-kl.de    sc_time non_overflow_time = sc_max_time() - m_curr_time;
90112027Sjungma@eit.uni-kl.de    if ( duration > non_overflow_time )
90212027Sjungma@eit.uni-kl.de    {
90312027Sjungma@eit.uni-kl.de	SC_REPORT_ERROR(SC_ID_SIMULATION_TIME_OVERFLOW_, "");
90412027Sjungma@eit.uni-kl.de	return;
90512027Sjungma@eit.uni-kl.de    }
90612027Sjungma@eit.uni-kl.de    else if ( duration < SC_ZERO_TIME )
90712027Sjungma@eit.uni-kl.de    {
90812027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR(SC_ID_NEGATIVE_SIMULATION_TIME_,"");
90912027Sjungma@eit.uni-kl.de    }
91012027Sjungma@eit.uni-kl.de
91112027Sjungma@eit.uni-kl.de    m_in_simulator_control = true;
91212027Sjungma@eit.uni-kl.de    m_paused = false;
91312027Sjungma@eit.uni-kl.de
91412027Sjungma@eit.uni-kl.de    sc_time until_t = m_curr_time + duration;
91512027Sjungma@eit.uni-kl.de    sc_time t;            // current simulaton time.
91612027Sjungma@eit.uni-kl.de
91712027Sjungma@eit.uni-kl.de    // IF DURATION WAS ZERO WE ONLY CRUNCH ONCE:
91812027Sjungma@eit.uni-kl.de    //
91912027Sjungma@eit.uni-kl.de    // We duplicate the code so that we don't add the overhead of the
92012027Sjungma@eit.uni-kl.de    // check to each loop in the do below.
92112027Sjungma@eit.uni-kl.de    if ( duration == SC_ZERO_TIME )
92212027Sjungma@eit.uni-kl.de    {
92312027Sjungma@eit.uni-kl.de	m_in_simulator_control = true;
92412027Sjungma@eit.uni-kl.de  	crunch( true );
92512027Sjungma@eit.uni-kl.de	if( m_error ) {
92612027Sjungma@eit.uni-kl.de	    m_in_simulator_control = false;
92712027Sjungma@eit.uni-kl.de	    return;
92812027Sjungma@eit.uni-kl.de	}
92912027Sjungma@eit.uni-kl.de#if SC_SIMCONTEXT_TRACING_
93012027Sjungma@eit.uni-kl.de        if( m_something_to_trace )
93112027Sjungma@eit.uni-kl.de            trace_cycle( /* delta cycle? */ false );
93212027Sjungma@eit.uni-kl.de#endif
93312027Sjungma@eit.uni-kl.de        if( m_forced_stop ) {
93412027Sjungma@eit.uni-kl.de            do_sc_stop_action();
93512027Sjungma@eit.uni-kl.de            return;
93612027Sjungma@eit.uni-kl.de        }
93712027Sjungma@eit.uni-kl.de        // return via implicit pause
93812027Sjungma@eit.uni-kl.de        goto exit_pause;
93912027Sjungma@eit.uni-kl.de    }
94012027Sjungma@eit.uni-kl.de
94112027Sjungma@eit.uni-kl.de    // NON-ZERO DURATION: EXECUTE UP TO THAT TIME, OR UNTIL EVENT STARVATION:
94212027Sjungma@eit.uni-kl.de
94312027Sjungma@eit.uni-kl.de    do {
94412027Sjungma@eit.uni-kl.de
94512027Sjungma@eit.uni-kl.de	crunch();
94612027Sjungma@eit.uni-kl.de	if( m_error ) {
94712027Sjungma@eit.uni-kl.de	    m_in_simulator_control = false;
94812027Sjungma@eit.uni-kl.de	    return;
94912027Sjungma@eit.uni-kl.de	}
95012027Sjungma@eit.uni-kl.de#if SC_SIMCONTEXT_TRACING_
95112027Sjungma@eit.uni-kl.de	if( m_something_to_trace ) {
95212027Sjungma@eit.uni-kl.de	    trace_cycle( false );
95312027Sjungma@eit.uni-kl.de	}
95412027Sjungma@eit.uni-kl.de#endif
95512027Sjungma@eit.uni-kl.de        // check for call(s) to sc_stop() or sc_pause().
95612027Sjungma@eit.uni-kl.de        if( m_forced_stop ) {
95712027Sjungma@eit.uni-kl.de            do_sc_stop_action();
95812027Sjungma@eit.uni-kl.de            return;
95912027Sjungma@eit.uni-kl.de        }
96012027Sjungma@eit.uni-kl.de        if( m_paused ) goto exit_pause; // return explicit pause
96112027Sjungma@eit.uni-kl.de
96212027Sjungma@eit.uni-kl.de	t = m_curr_time;
96312027Sjungma@eit.uni-kl.de
96412027Sjungma@eit.uni-kl.de	do {
96512027Sjungma@eit.uni-kl.de	    // See note 1 above:
96612027Sjungma@eit.uni-kl.de
96712027Sjungma@eit.uni-kl.de            if ( !next_time(t) || (t > until_t ) ) goto exit_time;
96812027Sjungma@eit.uni-kl.de	    if ( t > m_curr_time )
96912027Sjungma@eit.uni-kl.de	    {
97012027Sjungma@eit.uni-kl.de		SC_DO_PHASE_CALLBACK_(before_timestep);
97112027Sjungma@eit.uni-kl.de		m_curr_time = t;
97212027Sjungma@eit.uni-kl.de		m_change_stamp++;
97312027Sjungma@eit.uni-kl.de	    }
97412027Sjungma@eit.uni-kl.de
97512027Sjungma@eit.uni-kl.de	    // PROCESS TIMED NOTIFICATIONS AT THE CURRENT TIME
97612027Sjungma@eit.uni-kl.de
97712027Sjungma@eit.uni-kl.de	    do {
97812027Sjungma@eit.uni-kl.de		sc_event_timed* et = m_timed_events->extract_top();
97912027Sjungma@eit.uni-kl.de		sc_event* e = et->event();
98012027Sjungma@eit.uni-kl.de		delete et;
98112027Sjungma@eit.uni-kl.de		if( e != 0 ) {
98212027Sjungma@eit.uni-kl.de		    e->trigger();
98312027Sjungma@eit.uni-kl.de		}
98412027Sjungma@eit.uni-kl.de	    } while( m_timed_events->size() &&
98512027Sjungma@eit.uni-kl.de		     m_timed_events->top()->notify_time() == t );
98612027Sjungma@eit.uni-kl.de
98712027Sjungma@eit.uni-kl.de	} while( m_runnable->is_empty() );
98812027Sjungma@eit.uni-kl.de    } while ( t < until_t ); // hold off on the delta for the until_t time.
98912027Sjungma@eit.uni-kl.de
99012027Sjungma@eit.uni-kl.deexit_time:  // final simulation time update, if needed
99112027Sjungma@eit.uni-kl.de    if ( t > m_curr_time && t <= until_t )
99212027Sjungma@eit.uni-kl.de    {
99312027Sjungma@eit.uni-kl.de        SC_DO_PHASE_CALLBACK_(before_timestep);
99412027Sjungma@eit.uni-kl.de        m_curr_time = t;
99512027Sjungma@eit.uni-kl.de        m_change_stamp++;
99612027Sjungma@eit.uni-kl.de    }
99712027Sjungma@eit.uni-kl.deexit_pause: // call pause callback upon implicit or explicit pause
99812027Sjungma@eit.uni-kl.de    m_execution_phase      = phase_evaluate;
99912027Sjungma@eit.uni-kl.de    m_in_simulator_control = false;
100012027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(simulation_paused);
100112027Sjungma@eit.uni-kl.de}
100212027Sjungma@eit.uni-kl.de
100312027Sjungma@eit.uni-kl.devoid
100412027Sjungma@eit.uni-kl.desc_simcontext::do_sc_stop_action()
100512027Sjungma@eit.uni-kl.de{
100612027Sjungma@eit.uni-kl.de    SC_REPORT_INFO("/OSCI/SystemC","Simulation stopped by user.");
100712027Sjungma@eit.uni-kl.de    if (m_start_of_simulation_called) {
100812027Sjungma@eit.uni-kl.de	end();
100912027Sjungma@eit.uni-kl.de	m_in_simulator_control = false;
101012027Sjungma@eit.uni-kl.de    }
101112027Sjungma@eit.uni-kl.de    m_simulation_status = SC_STOPPED;
101212027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(simulation_stopped);
101312027Sjungma@eit.uni-kl.de}
101412027Sjungma@eit.uni-kl.de
101512027Sjungma@eit.uni-kl.devoid
101612027Sjungma@eit.uni-kl.desc_simcontext::mark_to_collect_process( sc_process_b* zombie )
101712027Sjungma@eit.uni-kl.de{
101812027Sjungma@eit.uni-kl.de    m_collectable->push_back( zombie );
101912027Sjungma@eit.uni-kl.de}
102012027Sjungma@eit.uni-kl.de
102112027Sjungma@eit.uni-kl.de
102212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
102312027Sjungma@eit.uni-kl.de//"sc_simcontext::stop"
102412027Sjungma@eit.uni-kl.de//
102512027Sjungma@eit.uni-kl.de// This method stops the simulator after some amount of further processing.
102612027Sjungma@eit.uni-kl.de// How much processing is done depends upon the value of the global variable
102712027Sjungma@eit.uni-kl.de// stop_mode:
102812027Sjungma@eit.uni-kl.de//     SC_STOP_IMMEDIATE - aborts the execution phase of the current delta
102912027Sjungma@eit.uni-kl.de//                         cycle and performs whatever updates are pending.
103012027Sjungma@eit.uni-kl.de//     SC_STOP_FINISH_DELTA - finishes the current delta cycle - both execution
103112027Sjungma@eit.uni-kl.de//                            and updates.
103212027Sjungma@eit.uni-kl.de// If sc_stop is called outside of the purview of the simulator kernel
103312027Sjungma@eit.uni-kl.de// (e.g., directly from sc_main), the end of simulation notifications
103412027Sjungma@eit.uni-kl.de// are performed. From within the purview of the simulator kernel, these
103512027Sjungma@eit.uni-kl.de// will be performed at a later time.
103612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
103712027Sjungma@eit.uni-kl.de
103812027Sjungma@eit.uni-kl.devoid
103912027Sjungma@eit.uni-kl.desc_simcontext::stop()
104012027Sjungma@eit.uni-kl.de{
104112027Sjungma@eit.uni-kl.de    static bool stop_warning_issued = false;
104212027Sjungma@eit.uni-kl.de    if (m_forced_stop)
104312027Sjungma@eit.uni-kl.de    {
104412027Sjungma@eit.uni-kl.de        if ( !stop_warning_issued )
104512027Sjungma@eit.uni-kl.de        {
104612027Sjungma@eit.uni-kl.de            stop_warning_issued = true; // This must be before the WARNING!!!
104712027Sjungma@eit.uni-kl.de            SC_REPORT_WARNING(SC_ID_SIMULATION_STOP_CALLED_TWICE_, "");
104812027Sjungma@eit.uni-kl.de        }
104912027Sjungma@eit.uni-kl.de        return;
105012027Sjungma@eit.uni-kl.de    }
105112027Sjungma@eit.uni-kl.de    if ( stop_mode == SC_STOP_IMMEDIATE ) m_runnable->init();
105212027Sjungma@eit.uni-kl.de    m_forced_stop = true;
105312027Sjungma@eit.uni-kl.de    if ( !m_in_simulator_control  )
105412027Sjungma@eit.uni-kl.de    {
105512027Sjungma@eit.uni-kl.de        do_sc_stop_action();
105612027Sjungma@eit.uni-kl.de    }
105712027Sjungma@eit.uni-kl.de}
105812027Sjungma@eit.uni-kl.de
105912027Sjungma@eit.uni-kl.devoid
106012027Sjungma@eit.uni-kl.desc_simcontext::reset()
106112027Sjungma@eit.uni-kl.de{
106212027Sjungma@eit.uni-kl.de    clean();
106312027Sjungma@eit.uni-kl.de    init();
106412027Sjungma@eit.uni-kl.de}
106512027Sjungma@eit.uni-kl.de
106612027Sjungma@eit.uni-kl.devoid
106712027Sjungma@eit.uni-kl.desc_simcontext::end()
106812027Sjungma@eit.uni-kl.de{
106912027Sjungma@eit.uni-kl.de    m_simulation_status = SC_END_OF_SIMULATION;
107012027Sjungma@eit.uni-kl.de    m_ready_to_simulate = false;
107112027Sjungma@eit.uni-kl.de    m_port_registry->simulation_done();
107212027Sjungma@eit.uni-kl.de    m_export_registry->simulation_done();
107312027Sjungma@eit.uni-kl.de    m_prim_channel_registry->simulation_done();
107412027Sjungma@eit.uni-kl.de    m_module_registry->simulation_done();
107512027Sjungma@eit.uni-kl.de    SC_DO_PHASE_CALLBACK_(simulation_done);
107612027Sjungma@eit.uni-kl.de    m_end_of_simulation_called = true;
107712027Sjungma@eit.uni-kl.de}
107812027Sjungma@eit.uni-kl.de
107912027Sjungma@eit.uni-kl.devoid
108012027Sjungma@eit.uni-kl.desc_simcontext::hierarchy_push( sc_module* mod )
108112027Sjungma@eit.uni-kl.de{
108212027Sjungma@eit.uni-kl.de    m_object_manager->hierarchy_push( mod );
108312027Sjungma@eit.uni-kl.de}
108412027Sjungma@eit.uni-kl.de
108512027Sjungma@eit.uni-kl.desc_module*
108612027Sjungma@eit.uni-kl.desc_simcontext::hierarchy_pop()
108712027Sjungma@eit.uni-kl.de{
108812027Sjungma@eit.uni-kl.de	return static_cast<sc_module*>( m_object_manager->hierarchy_pop() );
108912027Sjungma@eit.uni-kl.de}
109012027Sjungma@eit.uni-kl.de
109112027Sjungma@eit.uni-kl.desc_module*
109212027Sjungma@eit.uni-kl.desc_simcontext::hierarchy_curr() const
109312027Sjungma@eit.uni-kl.de{
109412027Sjungma@eit.uni-kl.de    return static_cast<sc_module*>( m_object_manager->hierarchy_curr() );
109512027Sjungma@eit.uni-kl.de}
109612027Sjungma@eit.uni-kl.de
109712027Sjungma@eit.uni-kl.desc_object*
109812027Sjungma@eit.uni-kl.desc_simcontext::first_object()
109912027Sjungma@eit.uni-kl.de{
110012027Sjungma@eit.uni-kl.de    return m_object_manager->first_object();
110112027Sjungma@eit.uni-kl.de}
110212027Sjungma@eit.uni-kl.de
110312027Sjungma@eit.uni-kl.desc_object*
110412027Sjungma@eit.uni-kl.desc_simcontext::next_object()
110512027Sjungma@eit.uni-kl.de{
110612027Sjungma@eit.uni-kl.de    return m_object_manager->next_object();
110712027Sjungma@eit.uni-kl.de}
110812027Sjungma@eit.uni-kl.de
110912027Sjungma@eit.uni-kl.desc_object*
111012027Sjungma@eit.uni-kl.desc_simcontext::find_object( const char* name )
111112027Sjungma@eit.uni-kl.de{
111212027Sjungma@eit.uni-kl.de    static bool warn_find_object=true;
111312027Sjungma@eit.uni-kl.de    if ( warn_find_object )
111412027Sjungma@eit.uni-kl.de    {
111512027Sjungma@eit.uni-kl.de	warn_find_object = false;
111612027Sjungma@eit.uni-kl.de	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
111712027Sjungma@eit.uni-kl.de	    "sc_simcontext::find_object() is deprecated,\n" \
111812027Sjungma@eit.uni-kl.de            " use sc_find_object()" );
111912027Sjungma@eit.uni-kl.de    }
112012027Sjungma@eit.uni-kl.de    return m_object_manager->find_object( name );
112112027Sjungma@eit.uni-kl.de}
112212027Sjungma@eit.uni-kl.de
112312027Sjungma@eit.uni-kl.de// to generate unique names for objects in an MT-Safe way
112412027Sjungma@eit.uni-kl.de
112512027Sjungma@eit.uni-kl.deconst char*
112612027Sjungma@eit.uni-kl.desc_simcontext::gen_unique_name( const char* basename_, bool preserve_first )
112712027Sjungma@eit.uni-kl.de{
112812027Sjungma@eit.uni-kl.de    return m_name_gen->gen_unique_name( basename_, preserve_first );
112912027Sjungma@eit.uni-kl.de}
113012027Sjungma@eit.uni-kl.de
113112027Sjungma@eit.uni-kl.de
113212027Sjungma@eit.uni-kl.desc_process_handle
113312027Sjungma@eit.uni-kl.desc_simcontext::create_cthread_process(
113412027Sjungma@eit.uni-kl.de    const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
113512027Sjungma@eit.uni-kl.de    sc_process_host* host_p, const sc_spawn_options* opt_p )
113612027Sjungma@eit.uni-kl.de{
113712027Sjungma@eit.uni-kl.de    sc_thread_handle handle =
113812027Sjungma@eit.uni-kl.de        new sc_cthread_process(name_p, free_host, method_p, host_p, opt_p);
113912027Sjungma@eit.uni-kl.de    if ( m_ready_to_simulate )
114012027Sjungma@eit.uni-kl.de    {
114112027Sjungma@eit.uni-kl.de	handle->prepare_for_simulation();
114212027Sjungma@eit.uni-kl.de    } else {
114312027Sjungma@eit.uni-kl.de	m_process_table->push_front( handle );
114412027Sjungma@eit.uni-kl.de    }
114512027Sjungma@eit.uni-kl.de    return sc_process_handle(handle);
114612027Sjungma@eit.uni-kl.de}
114712027Sjungma@eit.uni-kl.de
114812027Sjungma@eit.uni-kl.de
114912027Sjungma@eit.uni-kl.desc_process_handle
115012027Sjungma@eit.uni-kl.desc_simcontext::create_method_process(
115112027Sjungma@eit.uni-kl.de    const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
115212027Sjungma@eit.uni-kl.de    sc_process_host* host_p, const sc_spawn_options* opt_p )
115312027Sjungma@eit.uni-kl.de{
115412027Sjungma@eit.uni-kl.de    sc_method_handle handle =
115512027Sjungma@eit.uni-kl.de        new sc_method_process(name_p, free_host, method_p, host_p, opt_p);
115612027Sjungma@eit.uni-kl.de    if ( m_ready_to_simulate ) { // dynamic process
115712027Sjungma@eit.uni-kl.de	if ( !handle->dont_initialize() )
115812027Sjungma@eit.uni-kl.de        {
115912027Sjungma@eit.uni-kl.de#ifdef SC_HAS_PHASE_CALLBACKS_
116012027Sjungma@eit.uni-kl.de            if( SC_UNLIKELY_( m_simulation_status
116112027Sjungma@eit.uni-kl.de                            & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
116212027Sjungma@eit.uni-kl.de            {
116312027Sjungma@eit.uni-kl.de                std::stringstream msg;
116412027Sjungma@eit.uni-kl.de                msg << m_simulation_status
116512027Sjungma@eit.uni-kl.de                    << ":\n\t immediate method spawning of "
116612027Sjungma@eit.uni-kl.de                       "`" << handle->name() << "' ignored";
116712027Sjungma@eit.uni-kl.de                SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
116812027Sjungma@eit.uni-kl.de                                 , msg.str().c_str() );
116912027Sjungma@eit.uni-kl.de            }
117012027Sjungma@eit.uni-kl.de            else
117112027Sjungma@eit.uni-kl.de#endif // SC_HAS_PHASE_CALLBACKS_
117212027Sjungma@eit.uni-kl.de            {
117312027Sjungma@eit.uni-kl.de                push_runnable_method( handle );
117412027Sjungma@eit.uni-kl.de            }
117512027Sjungma@eit.uni-kl.de        }
117612027Sjungma@eit.uni-kl.de        else if ( handle->m_static_events.size() == 0 )
117712027Sjungma@eit.uni-kl.de        {
117812027Sjungma@eit.uni-kl.de            SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
117912027Sjungma@eit.uni-kl.de                               handle->name() );
118012027Sjungma@eit.uni-kl.de        }
118112027Sjungma@eit.uni-kl.de
118212027Sjungma@eit.uni-kl.de    } else {
118312027Sjungma@eit.uni-kl.de	m_process_table->push_front( handle );
118412027Sjungma@eit.uni-kl.de    }
118512027Sjungma@eit.uni-kl.de    return sc_process_handle(handle);
118612027Sjungma@eit.uni-kl.de}
118712027Sjungma@eit.uni-kl.de
118812027Sjungma@eit.uni-kl.de
118912027Sjungma@eit.uni-kl.desc_process_handle
119012027Sjungma@eit.uni-kl.desc_simcontext::create_thread_process(
119112027Sjungma@eit.uni-kl.de    const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
119212027Sjungma@eit.uni-kl.de    sc_process_host* host_p, const sc_spawn_options* opt_p )
119312027Sjungma@eit.uni-kl.de{
119412027Sjungma@eit.uni-kl.de    sc_thread_handle handle =
119512027Sjungma@eit.uni-kl.de        new sc_thread_process(name_p, free_host, method_p, host_p, opt_p);
119612027Sjungma@eit.uni-kl.de    if ( m_ready_to_simulate ) { // dynamic process
119712027Sjungma@eit.uni-kl.de	handle->prepare_for_simulation();
119812027Sjungma@eit.uni-kl.de        if ( !handle->dont_initialize() )
119912027Sjungma@eit.uni-kl.de        {
120012027Sjungma@eit.uni-kl.de#ifdef SC_HAS_PHASE_CALLBACKS_
120112027Sjungma@eit.uni-kl.de            if( SC_UNLIKELY_( m_simulation_status
120212027Sjungma@eit.uni-kl.de                            & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
120312027Sjungma@eit.uni-kl.de            {
120412027Sjungma@eit.uni-kl.de                std::stringstream msg;
120512027Sjungma@eit.uni-kl.de                msg << m_simulation_status
120612027Sjungma@eit.uni-kl.de                    << ":\n\t immediate thread spawning of "
120712027Sjungma@eit.uni-kl.de                       "`" << handle->name() << "' ignored";
120812027Sjungma@eit.uni-kl.de                SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
120912027Sjungma@eit.uni-kl.de                                 , msg.str().c_str() );
121012027Sjungma@eit.uni-kl.de            }
121112027Sjungma@eit.uni-kl.de            else
121212027Sjungma@eit.uni-kl.de#endif // SC_HAS_PHASE_CALLBACKS_
121312027Sjungma@eit.uni-kl.de            {
121412027Sjungma@eit.uni-kl.de                push_runnable_thread( handle );
121512027Sjungma@eit.uni-kl.de            }
121612027Sjungma@eit.uni-kl.de        }
121712027Sjungma@eit.uni-kl.de        else if ( handle->m_static_events.size() == 0 )
121812027Sjungma@eit.uni-kl.de        {
121912027Sjungma@eit.uni-kl.de            SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
122012027Sjungma@eit.uni-kl.de                               handle->name() );
122112027Sjungma@eit.uni-kl.de        }
122212027Sjungma@eit.uni-kl.de
122312027Sjungma@eit.uni-kl.de    } else {
122412027Sjungma@eit.uni-kl.de	m_process_table->push_front( handle );
122512027Sjungma@eit.uni-kl.de    }
122612027Sjungma@eit.uni-kl.de    return sc_process_handle(handle);
122712027Sjungma@eit.uni-kl.de}
122812027Sjungma@eit.uni-kl.de
122912027Sjungma@eit.uni-kl.devoid
123012027Sjungma@eit.uni-kl.desc_simcontext::add_trace_file( sc_trace_file* tf )
123112027Sjungma@eit.uni-kl.de{
123212027Sjungma@eit.uni-kl.de    m_trace_files.push_back( tf );
123312027Sjungma@eit.uni-kl.de    m_something_to_trace = true;
123412027Sjungma@eit.uni-kl.de}
123512027Sjungma@eit.uni-kl.de
123612027Sjungma@eit.uni-kl.devoid
123712027Sjungma@eit.uni-kl.desc_simcontext::remove_trace_file( sc_trace_file* tf )
123812027Sjungma@eit.uni-kl.de{
123912027Sjungma@eit.uni-kl.de    m_trace_files.erase(
124012027Sjungma@eit.uni-kl.de        std::remove( m_trace_files.begin(), m_trace_files.end(), tf )
124112027Sjungma@eit.uni-kl.de    );
124212027Sjungma@eit.uni-kl.de    m_something_to_trace = ( m_trace_files.size() > 0 );
124312027Sjungma@eit.uni-kl.de}
124412027Sjungma@eit.uni-kl.de
124512027Sjungma@eit.uni-kl.desc_cor*
124612027Sjungma@eit.uni-kl.desc_simcontext::next_cor()
124712027Sjungma@eit.uni-kl.de{
124812027Sjungma@eit.uni-kl.de    if( m_error ) {
124912027Sjungma@eit.uni-kl.de	return m_cor;
125012027Sjungma@eit.uni-kl.de    }
125112027Sjungma@eit.uni-kl.de
125212027Sjungma@eit.uni-kl.de    sc_thread_handle thread_h = pop_runnable_thread();
125312027Sjungma@eit.uni-kl.de    while( thread_h != 0 ) {
125412027Sjungma@eit.uni-kl.de	if ( thread_h->m_cor_p != NULL ) break;
125512027Sjungma@eit.uni-kl.de	thread_h = pop_runnable_thread();
125612027Sjungma@eit.uni-kl.de    }
125712027Sjungma@eit.uni-kl.de
125812027Sjungma@eit.uni-kl.de    if( thread_h != 0 ) {
125912027Sjungma@eit.uni-kl.de	return thread_h->m_cor_p;
126012027Sjungma@eit.uni-kl.de    } else {
126112027Sjungma@eit.uni-kl.de	return m_cor;
126212027Sjungma@eit.uni-kl.de    }
126312027Sjungma@eit.uni-kl.de}
126412027Sjungma@eit.uni-kl.de
126512027Sjungma@eit.uni-kl.deconst ::std::vector<sc_object*>&
126612027Sjungma@eit.uni-kl.desc_simcontext::get_child_objects() const
126712027Sjungma@eit.uni-kl.de{
126812027Sjungma@eit.uni-kl.de    static bool warn_get_child_objects=true;
126912027Sjungma@eit.uni-kl.de    if ( warn_get_child_objects )
127012027Sjungma@eit.uni-kl.de    {
127112027Sjungma@eit.uni-kl.de	warn_get_child_objects = false;
127212027Sjungma@eit.uni-kl.de	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
127312027Sjungma@eit.uni-kl.de	    "sc_simcontext::get_child_objects() is deprecated,\n" \
127412027Sjungma@eit.uni-kl.de            " use sc_get_top_level_objects()" );
127512027Sjungma@eit.uni-kl.de    }
127612027Sjungma@eit.uni-kl.de    return m_child_objects;
127712027Sjungma@eit.uni-kl.de}
127812027Sjungma@eit.uni-kl.de
127912027Sjungma@eit.uni-kl.devoid
128012027Sjungma@eit.uni-kl.desc_simcontext::add_child_event( sc_event* event_ )
128112027Sjungma@eit.uni-kl.de{
128212027Sjungma@eit.uni-kl.de    // no check if object_ is already in the set
128312027Sjungma@eit.uni-kl.de    m_child_events.push_back( event_ );
128412027Sjungma@eit.uni-kl.de}
128512027Sjungma@eit.uni-kl.de
128612027Sjungma@eit.uni-kl.devoid
128712027Sjungma@eit.uni-kl.desc_simcontext::add_child_object( sc_object* object_ )
128812027Sjungma@eit.uni-kl.de{
128912027Sjungma@eit.uni-kl.de    // no check if object_ is already in the set
129012027Sjungma@eit.uni-kl.de    m_child_objects.push_back( object_ );
129112027Sjungma@eit.uni-kl.de}
129212027Sjungma@eit.uni-kl.de
129312027Sjungma@eit.uni-kl.devoid
129412027Sjungma@eit.uni-kl.desc_simcontext::remove_child_event( sc_event* event_ )
129512027Sjungma@eit.uni-kl.de{
129612027Sjungma@eit.uni-kl.de    int size = m_child_events.size();
129712027Sjungma@eit.uni-kl.de    for( int i = 0; i < size; ++ i ) {
129812027Sjungma@eit.uni-kl.de	if( event_ == m_child_events[i] ) {
129912027Sjungma@eit.uni-kl.de	    m_child_events[i] = m_child_events[size - 1];
130012027Sjungma@eit.uni-kl.de	    m_child_events.resize(size-1);
130112027Sjungma@eit.uni-kl.de	    return;
130212027Sjungma@eit.uni-kl.de	}
130312027Sjungma@eit.uni-kl.de    }
130412027Sjungma@eit.uni-kl.de    // no check if event_ is really in the set
130512027Sjungma@eit.uni-kl.de}
130612027Sjungma@eit.uni-kl.de
130712027Sjungma@eit.uni-kl.devoid
130812027Sjungma@eit.uni-kl.desc_simcontext::remove_child_object( sc_object* object_ )
130912027Sjungma@eit.uni-kl.de{
131012027Sjungma@eit.uni-kl.de    int size = m_child_objects.size();
131112027Sjungma@eit.uni-kl.de    for( int i = 0; i < size; ++ i ) {
131212027Sjungma@eit.uni-kl.de	if( object_ == m_child_objects[i] ) {
131312027Sjungma@eit.uni-kl.de	    m_child_objects[i] = m_child_objects[size - 1];
131412027Sjungma@eit.uni-kl.de	    m_child_objects.resize(size-1);
131512027Sjungma@eit.uni-kl.de	    return;
131612027Sjungma@eit.uni-kl.de	}
131712027Sjungma@eit.uni-kl.de    }
131812027Sjungma@eit.uni-kl.de    // no check if object_ is really in the set
131912027Sjungma@eit.uni-kl.de}
132012027Sjungma@eit.uni-kl.de
132112027Sjungma@eit.uni-kl.desc_dt::uint64
132212027Sjungma@eit.uni-kl.desc_simcontext::delta_count() const
132312027Sjungma@eit.uni-kl.de{
132412027Sjungma@eit.uni-kl.de    static bool warn_delta_count=true;
132512027Sjungma@eit.uni-kl.de    if ( warn_delta_count )
132612027Sjungma@eit.uni-kl.de    {
132712027Sjungma@eit.uni-kl.de	warn_delta_count = false;
132812027Sjungma@eit.uni-kl.de	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
132912027Sjungma@eit.uni-kl.de	    "sc_simcontext::delta_count() is deprecated, use sc_delta_count()" );
133012027Sjungma@eit.uni-kl.de    }
133112027Sjungma@eit.uni-kl.de    return m_delta_count;
133212027Sjungma@eit.uni-kl.de}
133312027Sjungma@eit.uni-kl.de
133412027Sjungma@eit.uni-kl.debool
133512027Sjungma@eit.uni-kl.desc_simcontext::is_running() const
133612027Sjungma@eit.uni-kl.de{
133712027Sjungma@eit.uni-kl.de    static bool warn_is_running=true;
133812027Sjungma@eit.uni-kl.de    if ( warn_is_running )
133912027Sjungma@eit.uni-kl.de    {
134012027Sjungma@eit.uni-kl.de	warn_is_running = false;
134112027Sjungma@eit.uni-kl.de	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
134212027Sjungma@eit.uni-kl.de	    "sc_simcontext::is_running() is deprecated, use sc_is_running()" );
134312027Sjungma@eit.uni-kl.de    }
134412027Sjungma@eit.uni-kl.de    return m_ready_to_simulate;
134512027Sjungma@eit.uni-kl.de}
134612027Sjungma@eit.uni-kl.de
134712027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
134812027Sjungma@eit.uni-kl.de// |"sc_simcontext::next_time"
134912027Sjungma@eit.uni-kl.de// |
135012027Sjungma@eit.uni-kl.de// | This method returns the time of the next event. If there are no events
135112027Sjungma@eit.uni-kl.de// | it returns false.
135212027Sjungma@eit.uni-kl.de// |
135312027Sjungma@eit.uni-kl.de// | Arguments:
135412027Sjungma@eit.uni-kl.de// |     result = where to place time of the next event, if no event is
135512027Sjungma@eit.uni-kl.de// |              found this value will not be changed.
135612027Sjungma@eit.uni-kl.de// | Result is true if an event is found, false if not.
135712027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
135812027Sjungma@eit.uni-kl.debool
135912027Sjungma@eit.uni-kl.desc_simcontext::next_time( sc_time& result ) const
136012027Sjungma@eit.uni-kl.de{
136112027Sjungma@eit.uni-kl.de    while( m_timed_events->size() ) {
136212027Sjungma@eit.uni-kl.de	sc_event_timed* et = m_timed_events->top();
136312027Sjungma@eit.uni-kl.de	if( et->event() != 0 ) {
136412027Sjungma@eit.uni-kl.de	    result = et->notify_time();
136512027Sjungma@eit.uni-kl.de	    return true;
136612027Sjungma@eit.uni-kl.de	}
136712027Sjungma@eit.uni-kl.de	delete m_timed_events->extract_top();
136812027Sjungma@eit.uni-kl.de    }
136912027Sjungma@eit.uni-kl.de    return false;
137012027Sjungma@eit.uni-kl.de}
137112027Sjungma@eit.uni-kl.de
137212027Sjungma@eit.uni-kl.devoid
137312027Sjungma@eit.uni-kl.desc_simcontext::remove_delta_event( sc_event* e )
137412027Sjungma@eit.uni-kl.de{
137512027Sjungma@eit.uni-kl.de    int i = e->m_delta_event_index;
137612027Sjungma@eit.uni-kl.de    int j = m_delta_events.size() - 1;
137712027Sjungma@eit.uni-kl.de    assert( i >= 0 && i <= j );
137812027Sjungma@eit.uni-kl.de    if( i != j ) {
137912027Sjungma@eit.uni-kl.de	sc_event** l_delta_events = &m_delta_events[0];
138012027Sjungma@eit.uni-kl.de	l_delta_events[i] = l_delta_events[j];
138112027Sjungma@eit.uni-kl.de	l_delta_events[i]->m_delta_event_index = i;
138212027Sjungma@eit.uni-kl.de    }
138312027Sjungma@eit.uni-kl.de    m_delta_events.resize(m_delta_events.size()-1);
138412027Sjungma@eit.uni-kl.de    e->m_delta_event_index = -1;
138512027Sjungma@eit.uni-kl.de}
138612027Sjungma@eit.uni-kl.de
138712027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
138812027Sjungma@eit.uni-kl.de// |"sc_simcontext::preempt_with"
138912027Sjungma@eit.uni-kl.de// |
139012027Sjungma@eit.uni-kl.de// | This method executes the supplied method immediately, suspending the
139112027Sjungma@eit.uni-kl.de// | caller. After executing the supplied method the caller's execution will
139212027Sjungma@eit.uni-kl.de// | be restored. It is used to allow a method to immediately throw an
139312027Sjungma@eit.uni-kl.de// | exception, e.g., when the method's kill_process() method was called.
139412027Sjungma@eit.uni-kl.de// | There are three cases to consider:
139512027Sjungma@eit.uni-kl.de// |   (1) The caller is a method, e.g., murder by method.
139612027Sjungma@eit.uni-kl.de// |   (2) The caller is a thread instance, e.g., murder by thread.
139712027Sjungma@eit.uni-kl.de// |   (3) The caller is this method instance, e.g., suicide.
139812027Sjungma@eit.uni-kl.de// |
139912027Sjungma@eit.uni-kl.de// | Arguments:
140012027Sjungma@eit.uni-kl.de// |     method_h -> method to be executed.
140112027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
140212027Sjungma@eit.uni-kl.devoid
140312027Sjungma@eit.uni-kl.desc_simcontext::preempt_with( sc_method_handle method_h )
140412027Sjungma@eit.uni-kl.de{
140512027Sjungma@eit.uni-kl.de    sc_curr_proc_info caller_info;     // process info for caller.
140612027Sjungma@eit.uni-kl.de    sc_method_handle  active_method_h; // active method or null.
140712027Sjungma@eit.uni-kl.de    sc_thread_handle  active_thread_h; // active thread or null.
140812027Sjungma@eit.uni-kl.de
140912027Sjungma@eit.uni-kl.de    // Determine the active process and take the thread to be run off the
141012027Sjungma@eit.uni-kl.de    // run queue, if its there, since we will be explicitly causing its
141112027Sjungma@eit.uni-kl.de    // execution.
141212027Sjungma@eit.uni-kl.de
141312027Sjungma@eit.uni-kl.de    active_method_h = DCAST<sc_method_handle>(sc_get_current_process_b());
141412027Sjungma@eit.uni-kl.de    active_thread_h = DCAST<sc_thread_handle>(sc_get_current_process_b());
141512027Sjungma@eit.uni-kl.de    if ( method_h->next_runnable() != NULL )
141612027Sjungma@eit.uni-kl.de	remove_runnable_method( method_h );
141712027Sjungma@eit.uni-kl.de
141812027Sjungma@eit.uni-kl.de    // CALLER IS THE METHOD TO BE RUN:
141912027Sjungma@eit.uni-kl.de    //
142012027Sjungma@eit.uni-kl.de    // Should never get here, ignore it unless we are debugging.
142112027Sjungma@eit.uni-kl.de
142212027Sjungma@eit.uni-kl.de    if ( method_h == active_method_h )
142312027Sjungma@eit.uni-kl.de    {
142412027Sjungma@eit.uni-kl.de        DEBUG_MSG(DEBUG_NAME,method_h,"self preemption of active method");
142512027Sjungma@eit.uni-kl.de    }
142612027Sjungma@eit.uni-kl.de
142712027Sjungma@eit.uni-kl.de    // THE CALLER IS A METHOD:
142812027Sjungma@eit.uni-kl.de    //
142912027Sjungma@eit.uni-kl.de    //   (a) Set the current process information to our method.
143012027Sjungma@eit.uni-kl.de    //   (b) Invoke our method directly by-passing the run queue.
143112027Sjungma@eit.uni-kl.de    //   (c) Restore the process info to the caller.
143212027Sjungma@eit.uni-kl.de    //   (d) Check to see if the calling method should throw an exception
143312027Sjungma@eit.uni-kl.de    //       because of activity that occurred during the preemption.
143412027Sjungma@eit.uni-kl.de
143512027Sjungma@eit.uni-kl.de    else if ( active_method_h != NULL )
143612027Sjungma@eit.uni-kl.de    {
143712027Sjungma@eit.uni-kl.de	caller_info = m_curr_proc_info;
143812027Sjungma@eit.uni-kl.de        DEBUG_MSG( DEBUG_NAME, method_h,
143912027Sjungma@eit.uni-kl.de	           "preempting active method with method" );
144012027Sjungma@eit.uni-kl.de	sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
144112027Sjungma@eit.uni-kl.de	method_h->run_process();
144212027Sjungma@eit.uni-kl.de	sc_get_curr_simcontext()->set_curr_proc((sc_process_b*)active_method_h);
144312027Sjungma@eit.uni-kl.de	active_method_h->check_for_throws();
144412027Sjungma@eit.uni-kl.de    }
144512027Sjungma@eit.uni-kl.de
144612027Sjungma@eit.uni-kl.de    // CALLER IS A THREAD:
144712027Sjungma@eit.uni-kl.de    //
144812027Sjungma@eit.uni-kl.de    //   (a) Use an invocation thread to execute the method.
144912027Sjungma@eit.uni-kl.de
145012027Sjungma@eit.uni-kl.de    else if ( active_thread_h != NULL )
145112027Sjungma@eit.uni-kl.de    {
145212027Sjungma@eit.uni-kl.de        DEBUG_MSG( DEBUG_NAME, method_h,
145312027Sjungma@eit.uni-kl.de	           "preempting active thread with method" );
145412027Sjungma@eit.uni-kl.de	m_method_invoker_p->invoke_method(method_h);
145512027Sjungma@eit.uni-kl.de    }
145612027Sjungma@eit.uni-kl.de
145712027Sjungma@eit.uni-kl.de    // CALLER IS THE SIMULATOR:
145812027Sjungma@eit.uni-kl.de    //
145912027Sjungma@eit.uni-kl.de    // That is not allowed.
146012027Sjungma@eit.uni-kl.de
146112027Sjungma@eit.uni-kl.de    else
146212027Sjungma@eit.uni-kl.de    {
146312027Sjungma@eit.uni-kl.de	caller_info = m_curr_proc_info;
146412027Sjungma@eit.uni-kl.de        DEBUG_MSG( DEBUG_NAME, method_h,
146512027Sjungma@eit.uni-kl.de	           "preempting no active process with method" );
146612027Sjungma@eit.uni-kl.de	sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
146712027Sjungma@eit.uni-kl.de	method_h->run_process();
146812027Sjungma@eit.uni-kl.de	m_curr_proc_info = caller_info;
146912027Sjungma@eit.uni-kl.de    }
147012027Sjungma@eit.uni-kl.de}
147112027Sjungma@eit.uni-kl.de
147212027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
147312027Sjungma@eit.uni-kl.de//"sc_simcontext::requeue_current_process"
147412027Sjungma@eit.uni-kl.de//
147512027Sjungma@eit.uni-kl.de// This method requeues the current process at the beginning of the run queue
147612027Sjungma@eit.uni-kl.de// if it is a thread. This is called by sc_process_handle::throw_it() to assure
147712027Sjungma@eit.uni-kl.de// that a thread that is issuing a throw will execute immediately after the
147812027Sjungma@eit.uni-kl.de// processes it notifies via the throw.
147912027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
148012027Sjungma@eit.uni-kl.devoid sc_simcontext::requeue_current_process()
148112027Sjungma@eit.uni-kl.de{
148212027Sjungma@eit.uni-kl.de    sc_thread_handle thread_p;
148312027Sjungma@eit.uni-kl.de    thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
148412027Sjungma@eit.uni-kl.de    if ( thread_p )
148512027Sjungma@eit.uni-kl.de    {
148612027Sjungma@eit.uni-kl.de	execute_thread_next( thread_p );
148712027Sjungma@eit.uni-kl.de    }
148812027Sjungma@eit.uni-kl.de}
148912027Sjungma@eit.uni-kl.de
149012027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
149112027Sjungma@eit.uni-kl.de//"sc_simcontext::suspend_current_process"
149212027Sjungma@eit.uni-kl.de//
149312027Sjungma@eit.uni-kl.de// This method suspends the current process if it is a thread. This is called
149412027Sjungma@eit.uni-kl.de// by sc_process_handle::throw_it() to allow the processes that have received
149512027Sjungma@eit.uni-kl.de// a throw to execute.
149612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
149712027Sjungma@eit.uni-kl.devoid sc_simcontext::suspend_current_process()
149812027Sjungma@eit.uni-kl.de{
149912027Sjungma@eit.uni-kl.de    sc_thread_handle thread_p;
150012027Sjungma@eit.uni-kl.de    thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
150112027Sjungma@eit.uni-kl.de    if ( thread_p )
150212027Sjungma@eit.uni-kl.de    {
150312027Sjungma@eit.uni-kl.de	thread_p->suspend_me();
150412027Sjungma@eit.uni-kl.de    }
150512027Sjungma@eit.uni-kl.de}
150612027Sjungma@eit.uni-kl.de
150712027Sjungma@eit.uni-kl.devoid
150812027Sjungma@eit.uni-kl.desc_simcontext::trace_cycle( bool delta_cycle )
150912027Sjungma@eit.uni-kl.de{
151012027Sjungma@eit.uni-kl.de    int size;
151112027Sjungma@eit.uni-kl.de    if( ( size = m_trace_files.size() ) != 0 ) {
151212027Sjungma@eit.uni-kl.de	sc_trace_file** l_trace_files = &m_trace_files[0];
151312027Sjungma@eit.uni-kl.de	int i = size - 1;
151412027Sjungma@eit.uni-kl.de	do {
151512027Sjungma@eit.uni-kl.de	    l_trace_files[i]->cycle( delta_cycle );
151612027Sjungma@eit.uni-kl.de	} while( -- i >= 0 );
151712027Sjungma@eit.uni-kl.de    }
151812027Sjungma@eit.uni-kl.de}
151912027Sjungma@eit.uni-kl.de
152012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
152112027Sjungma@eit.uni-kl.de
152212027Sjungma@eit.uni-kl.de#if 1
152312027Sjungma@eit.uni-kl.de#ifdef PURIFY
152412027Sjungma@eit.uni-kl.de	static sc_simcontext sc_default_global_context;
152512027Sjungma@eit.uni-kl.de	sc_simcontext* sc_curr_simcontext = &sc_default_global_context;
152612027Sjungma@eit.uni-kl.de#else
152712027Sjungma@eit.uni-kl.de	sc_simcontext* sc_curr_simcontext = 0;
152812027Sjungma@eit.uni-kl.de	sc_simcontext* sc_default_global_context = 0;
152912027Sjungma@eit.uni-kl.de#endif
153012027Sjungma@eit.uni-kl.de#else
153112027Sjungma@eit.uni-kl.de// Not MT-safe!
153212027Sjungma@eit.uni-kl.destatic sc_simcontext* sc_curr_simcontext = 0;
153312027Sjungma@eit.uni-kl.de
153412027Sjungma@eit.uni-kl.de
153512027Sjungma@eit.uni-kl.desc_simcontext*
153612027Sjungma@eit.uni-kl.desc_get_curr_simcontext()
153712027Sjungma@eit.uni-kl.de{
153812027Sjungma@eit.uni-kl.de    if( sc_curr_simcontext == 0 ) {
153912027Sjungma@eit.uni-kl.de#ifdef PURIFY
154012027Sjungma@eit.uni-kl.de        static sc_simcontext sc_default_global_context;
154112027Sjungma@eit.uni-kl.de        sc_curr_simcontext = &sc_default_global_context;
154212027Sjungma@eit.uni-kl.de#else
154312027Sjungma@eit.uni-kl.de        static sc_simcontext* sc_default_global_context = new sc_simcontext;
154412027Sjungma@eit.uni-kl.de        sc_curr_simcontext = sc_default_global_context;
154512027Sjungma@eit.uni-kl.de#endif
154612027Sjungma@eit.uni-kl.de    }
154712027Sjungma@eit.uni-kl.de    return sc_curr_simcontext;
154812027Sjungma@eit.uni-kl.de}
154912027Sjungma@eit.uni-kl.de#endif // 0
155012027Sjungma@eit.uni-kl.de
155112027Sjungma@eit.uni-kl.de// Generates unique names within each module.
155212027Sjungma@eit.uni-kl.de
155312027Sjungma@eit.uni-kl.deconst char*
155412027Sjungma@eit.uni-kl.desc_gen_unique_name( const char* basename_, bool preserve_first )
155512027Sjungma@eit.uni-kl.de{
155612027Sjungma@eit.uni-kl.de    sc_simcontext* simc = sc_get_curr_simcontext();
155712027Sjungma@eit.uni-kl.de    sc_module* curr_module = simc->hierarchy_curr();
155812027Sjungma@eit.uni-kl.de    if( curr_module != 0 ) {
155912027Sjungma@eit.uni-kl.de	return curr_module->gen_unique_name( basename_, preserve_first );
156012027Sjungma@eit.uni-kl.de    } else {
156112027Sjungma@eit.uni-kl.de        sc_process_b* curr_proc_p = sc_get_current_process_b();
156212027Sjungma@eit.uni-kl.de	if ( curr_proc_p )
156312027Sjungma@eit.uni-kl.de	{
156412027Sjungma@eit.uni-kl.de	    return curr_proc_p->gen_unique_name( basename_, preserve_first );
156512027Sjungma@eit.uni-kl.de	}
156612027Sjungma@eit.uni-kl.de	else
156712027Sjungma@eit.uni-kl.de	{
156812027Sjungma@eit.uni-kl.de	    return simc->gen_unique_name( basename_, preserve_first );
156912027Sjungma@eit.uni-kl.de	}
157012027Sjungma@eit.uni-kl.de    }
157112027Sjungma@eit.uni-kl.de}
157212027Sjungma@eit.uni-kl.de
157312027Sjungma@eit.uni-kl.de// Get a handle for the current process
157412027Sjungma@eit.uni-kl.de//
157512027Sjungma@eit.uni-kl.de// Note that this method should not be called if the current process is
157612027Sjungma@eit.uni-kl.de// in the act of being deleted, it will mess up the reference count management
157712027Sjungma@eit.uni-kl.de// of sc_process_b instance the handle represents. Instead, use the a
157812027Sjungma@eit.uni-kl.de// pointer to the raw sc_process_b instance, which may be acquired via
157912027Sjungma@eit.uni-kl.de// sc_get_current_process_b().
158012027Sjungma@eit.uni-kl.de
158112027Sjungma@eit.uni-kl.desc_process_handle
158212027Sjungma@eit.uni-kl.desc_get_current_process_handle()
158312027Sjungma@eit.uni-kl.de{
158412027Sjungma@eit.uni-kl.de    return ( sc_is_running() ) ?
158512027Sjungma@eit.uni-kl.de	sc_process_handle(sc_get_current_process_b()) :
158612027Sjungma@eit.uni-kl.de	sc_get_last_created_process_handle();
158712027Sjungma@eit.uni-kl.de}
158812027Sjungma@eit.uni-kl.de
158912027Sjungma@eit.uni-kl.de// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
159012027Sjungma@eit.uni-kl.desc_process_b*
159112027Sjungma@eit.uni-kl.desc_get_curr_process_handle()
159212027Sjungma@eit.uni-kl.de{
159312027Sjungma@eit.uni-kl.de    static bool warn=true;
159412027Sjungma@eit.uni-kl.de    if ( warn )
159512027Sjungma@eit.uni-kl.de    {
159612027Sjungma@eit.uni-kl.de        warn = false;
159712027Sjungma@eit.uni-kl.de        SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
159812027Sjungma@eit.uni-kl.de       "sc_get_curr_process_handle deprecated use sc_get_current_process_handle"
159912027Sjungma@eit.uni-kl.de       );
160012027Sjungma@eit.uni-kl.de    }
160112027Sjungma@eit.uni-kl.de
160212027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
160312027Sjungma@eit.uni-kl.de}
160412027Sjungma@eit.uni-kl.de
160512027Sjungma@eit.uni-kl.de// Return indication if there are more processes to execute in this delta phase
160612027Sjungma@eit.uni-kl.de
160712027Sjungma@eit.uni-kl.debool
160812027Sjungma@eit.uni-kl.desc_simcontext::pending_activity_at_current_time() const
160912027Sjungma@eit.uni-kl.de{
161012027Sjungma@eit.uni-kl.de    return ( m_delta_events.size() != 0) ||
161112027Sjungma@eit.uni-kl.de           ( m_runnable->is_initialized() && !m_runnable->is_empty() ) ||
161212027Sjungma@eit.uni-kl.de           m_prim_channel_registry->pending_updates();
161312027Sjungma@eit.uni-kl.de}
161412027Sjungma@eit.uni-kl.de
161512027Sjungma@eit.uni-kl.de// Return time of next activity.
161612027Sjungma@eit.uni-kl.de
161712027Sjungma@eit.uni-kl.desc_time sc_time_to_pending_activity( const sc_simcontext* simc_p )
161812027Sjungma@eit.uni-kl.de{
161912027Sjungma@eit.uni-kl.de    // If there is an activity pending at the current time
162012027Sjungma@eit.uni-kl.de    // return a delta of zero.
162112027Sjungma@eit.uni-kl.de
162212027Sjungma@eit.uni-kl.de    sc_time result=SC_ZERO_TIME; // time of pending activity.
162312027Sjungma@eit.uni-kl.de
162412027Sjungma@eit.uni-kl.de    if ( simc_p->pending_activity_at_current_time() )
162512027Sjungma@eit.uni-kl.de    {
162612027Sjungma@eit.uni-kl.de        return result;
162712027Sjungma@eit.uni-kl.de    }
162812027Sjungma@eit.uni-kl.de
162912027Sjungma@eit.uni-kl.de    // Any activity will take place in the future pick up the next event's time.
163012027Sjungma@eit.uni-kl.de
163112027Sjungma@eit.uni-kl.de    else
163212027Sjungma@eit.uni-kl.de    {
163312027Sjungma@eit.uni-kl.de        result = simc_p->max_time();
163412027Sjungma@eit.uni-kl.de        simc_p->next_time(result);
163512027Sjungma@eit.uni-kl.de        result -= sc_time_stamp();
163612027Sjungma@eit.uni-kl.de    }
163712027Sjungma@eit.uni-kl.de    return result;
163812027Sjungma@eit.uni-kl.de}
163912027Sjungma@eit.uni-kl.de
164012027Sjungma@eit.uni-kl.de// Set the random seed for controlled randomization -- not yet implemented
164112027Sjungma@eit.uni-kl.de
164212027Sjungma@eit.uni-kl.devoid
164312027Sjungma@eit.uni-kl.desc_set_random_seed( unsigned int )
164412027Sjungma@eit.uni-kl.de{
164512027Sjungma@eit.uni-kl.de    SC_REPORT_WARNING( SC_ID_NOT_IMPLEMENTED_,
164612027Sjungma@eit.uni-kl.de		       "void sc_set_random_seed( unsigned int )" );
164712027Sjungma@eit.uni-kl.de}
164812027Sjungma@eit.uni-kl.de
164912027Sjungma@eit.uni-kl.de
165012027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
165112027Sjungma@eit.uni-kl.de// |"sc_start"
165212027Sjungma@eit.uni-kl.de// |
165312027Sjungma@eit.uni-kl.de// | This function starts, or restarts, the execution of the simulator.
165412027Sjungma@eit.uni-kl.de// |
165512027Sjungma@eit.uni-kl.de// | Arguments:
165612027Sjungma@eit.uni-kl.de// |     duration = the amount of time the simulator should execute.
165712027Sjungma@eit.uni-kl.de// |     p        = event starvation policy.
165812027Sjungma@eit.uni-kl.de// +----------------------------------------------------------------------------
165912027Sjungma@eit.uni-kl.devoid
166012027Sjungma@eit.uni-kl.desc_start( const sc_time& duration, sc_starvation_policy p )
166112027Sjungma@eit.uni-kl.de{
166212027Sjungma@eit.uni-kl.de    sc_simcontext* context_p;      // current simulation context.
166312027Sjungma@eit.uni-kl.de    sc_time        entry_time;     // simulation time upon entry.
166412027Sjungma@eit.uni-kl.de    sc_time        exit_time;      // simulation time to set upon exit.
166512027Sjungma@eit.uni-kl.de    sc_dt::uint64  starting_delta; // delta count upon entry.
166612027Sjungma@eit.uni-kl.de    int            status;         // current simulation status.
166712027Sjungma@eit.uni-kl.de
166812027Sjungma@eit.uni-kl.de    // Set up based on the arguments passed to us:
166912027Sjungma@eit.uni-kl.de
167012027Sjungma@eit.uni-kl.de    context_p = sc_get_curr_simcontext();
167112027Sjungma@eit.uni-kl.de    starting_delta = sc_delta_count();
167212027Sjungma@eit.uni-kl.de    entry_time = context_p->m_curr_time;
167312027Sjungma@eit.uni-kl.de    if ( p == SC_RUN_TO_TIME )
167412027Sjungma@eit.uni-kl.de        exit_time = context_p->m_curr_time + duration;
167512027Sjungma@eit.uni-kl.de
167612027Sjungma@eit.uni-kl.de    // called with duration = SC_ZERO_TIME for the first time
167712027Sjungma@eit.uni-kl.de    static bool init_delta_or_pending_updates =
167812027Sjungma@eit.uni-kl.de         ( starting_delta == 0 && exit_time == SC_ZERO_TIME );
167912027Sjungma@eit.uni-kl.de
168012027Sjungma@eit.uni-kl.de    // If the simulation status is bad issue the appropriate message:
168112027Sjungma@eit.uni-kl.de
168212027Sjungma@eit.uni-kl.de    status = context_p->sim_status();
168312027Sjungma@eit.uni-kl.de    if( status != SC_SIM_OK )
168412027Sjungma@eit.uni-kl.de    {
168512027Sjungma@eit.uni-kl.de        if ( status == SC_SIM_USER_STOP )
168612027Sjungma@eit.uni-kl.de            SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_STOP_, "");
168712027Sjungma@eit.uni-kl.de        if ( status == SC_SIM_ERROR )
168812027Sjungma@eit.uni-kl.de            SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_ERROR_, "");
168912027Sjungma@eit.uni-kl.de        return;
169012027Sjungma@eit.uni-kl.de    }
169112027Sjungma@eit.uni-kl.de
169212027Sjungma@eit.uni-kl.de    if ( context_p->m_prim_channel_registry->pending_updates() )
169312027Sjungma@eit.uni-kl.de        init_delta_or_pending_updates = true;
169412027Sjungma@eit.uni-kl.de
169512027Sjungma@eit.uni-kl.de    // If the simulation status is good perform the simulation:
169612027Sjungma@eit.uni-kl.de
169712027Sjungma@eit.uni-kl.de    context_p->simulate( duration );
169812027Sjungma@eit.uni-kl.de
169912027Sjungma@eit.uni-kl.de    // Re-check the status:
170012027Sjungma@eit.uni-kl.de
170112027Sjungma@eit.uni-kl.de    status = context_p->sim_status();
170212027Sjungma@eit.uni-kl.de
170312027Sjungma@eit.uni-kl.de    // Update the current time to the exit time if that is the starvation
170412027Sjungma@eit.uni-kl.de    // policy:
170512027Sjungma@eit.uni-kl.de
170612027Sjungma@eit.uni-kl.de    if ( p == SC_RUN_TO_TIME && !context_p->m_paused && status == SC_SIM_OK )
170712027Sjungma@eit.uni-kl.de    {
170812027Sjungma@eit.uni-kl.de        context_p->m_curr_time = exit_time;
170912027Sjungma@eit.uni-kl.de    }
171012027Sjungma@eit.uni-kl.de
171112027Sjungma@eit.uni-kl.de    // If there was no activity and the simulation clock did not move warn
171212027Sjungma@eit.uni-kl.de    // the user, except if we're in a first sc_start(SC_ZERO_TIME) for
171312027Sjungma@eit.uni-kl.de    // initialisation (only) or there have been pending updates:
171412027Sjungma@eit.uni-kl.de
171512027Sjungma@eit.uni-kl.de    if ( !init_delta_or_pending_updates &&
171612027Sjungma@eit.uni-kl.de         starting_delta == sc_delta_count() &&
171712027Sjungma@eit.uni-kl.de         context_p->m_curr_time == entry_time &&
171812027Sjungma@eit.uni-kl.de         status == SC_SIM_OK )
171912027Sjungma@eit.uni-kl.de    {
172012027Sjungma@eit.uni-kl.de        SC_REPORT_WARNING(SC_ID_NO_SC_START_ACTIVITY_, "");
172112027Sjungma@eit.uni-kl.de    }
172212027Sjungma@eit.uni-kl.de
172312027Sjungma@eit.uni-kl.de    // reset init/update flag for subsequent calls
172412027Sjungma@eit.uni-kl.de    init_delta_or_pending_updates = false;
172512027Sjungma@eit.uni-kl.de}
172612027Sjungma@eit.uni-kl.de
172712027Sjungma@eit.uni-kl.devoid
172812027Sjungma@eit.uni-kl.desc_start()
172912027Sjungma@eit.uni-kl.de{
173012027Sjungma@eit.uni-kl.de    sc_start( sc_max_time() - sc_time_stamp(),
173112027Sjungma@eit.uni-kl.de              SC_EXIT_ON_STARVATION );
173212027Sjungma@eit.uni-kl.de}
173312027Sjungma@eit.uni-kl.de
173412027Sjungma@eit.uni-kl.de// for backward compatibility with 1.0
173512027Sjungma@eit.uni-kl.de#if 0
173612027Sjungma@eit.uni-kl.devoid
173712027Sjungma@eit.uni-kl.desc_start( double duration )  // in default time units
173812027Sjungma@eit.uni-kl.de{
173912027Sjungma@eit.uni-kl.de    static bool warn_sc_start=true;
174012027Sjungma@eit.uni-kl.de    if ( warn_sc_start )
174112027Sjungma@eit.uni-kl.de    {
174212027Sjungma@eit.uni-kl.de	warn_sc_start = false;
174312027Sjungma@eit.uni-kl.de	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
174412027Sjungma@eit.uni-kl.de	    "sc_start(double) deprecated, use sc_start(sc_time) or sc_start()");
174512027Sjungma@eit.uni-kl.de    }
174612027Sjungma@eit.uni-kl.de
174712027Sjungma@eit.uni-kl.de    if( duration == -1 )  // simulate forever
174812027Sjungma@eit.uni-kl.de    {
174912027Sjungma@eit.uni-kl.de        sc_start(
175012027Sjungma@eit.uni-kl.de            sc_time(~sc_dt::UINT64_ZERO, false) - sc_time_stamp() );
175112027Sjungma@eit.uni-kl.de    }
175212027Sjungma@eit.uni-kl.de    else
175312027Sjungma@eit.uni-kl.de    {
175412027Sjungma@eit.uni-kl.de        sc_start( sc_time( duration, true ) );
175512027Sjungma@eit.uni-kl.de    }
175612027Sjungma@eit.uni-kl.de}
175712027Sjungma@eit.uni-kl.de#endif //
175812027Sjungma@eit.uni-kl.de
175912027Sjungma@eit.uni-kl.devoid
176012027Sjungma@eit.uni-kl.desc_stop()
176112027Sjungma@eit.uni-kl.de{
176212027Sjungma@eit.uni-kl.de    sc_get_curr_simcontext()->stop();
176312027Sjungma@eit.uni-kl.de}
176412027Sjungma@eit.uni-kl.de
176512027Sjungma@eit.uni-kl.de
176612027Sjungma@eit.uni-kl.de// The following function is deprecated in favor of sc_start(SC_ZERO_TIME):
176712027Sjungma@eit.uni-kl.de
176812027Sjungma@eit.uni-kl.devoid
176912027Sjungma@eit.uni-kl.desc_initialize()
177012027Sjungma@eit.uni-kl.de{
177112027Sjungma@eit.uni-kl.de    static bool warning_initialize = true;
177212027Sjungma@eit.uni-kl.de
177312027Sjungma@eit.uni-kl.de    if ( warning_initialize )
177412027Sjungma@eit.uni-kl.de    {
177512027Sjungma@eit.uni-kl.de        warning_initialize = false;
177612027Sjungma@eit.uni-kl.de        SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
177712027Sjungma@eit.uni-kl.de	    "sc_initialize() is deprecated: use sc_start(SC_ZERO_TIME)" );
177812027Sjungma@eit.uni-kl.de    }
177912027Sjungma@eit.uni-kl.de    sc_get_curr_simcontext()->initialize();
178012027Sjungma@eit.uni-kl.de}
178112027Sjungma@eit.uni-kl.de
178212027Sjungma@eit.uni-kl.de// The following function has been deprecated in favor of sc_start(duration):
178312027Sjungma@eit.uni-kl.de
178412027Sjungma@eit.uni-kl.devoid
178512027Sjungma@eit.uni-kl.desc_cycle( const sc_time& duration )
178612027Sjungma@eit.uni-kl.de{
178712027Sjungma@eit.uni-kl.de    static bool warning_cycle = true;
178812027Sjungma@eit.uni-kl.de
178912027Sjungma@eit.uni-kl.de    if ( warning_cycle )
179012027Sjungma@eit.uni-kl.de    {
179112027Sjungma@eit.uni-kl.de        warning_cycle = false;
179212027Sjungma@eit.uni-kl.de        SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
179312027Sjungma@eit.uni-kl.de	    "sc_cycle is deprecated: use sc_start(sc_time)" );
179412027Sjungma@eit.uni-kl.de    }
179512027Sjungma@eit.uni-kl.de    sc_get_curr_simcontext()->cycle( duration );
179612027Sjungma@eit.uni-kl.de}
179712027Sjungma@eit.uni-kl.de
179812027Sjungma@eit.uni-kl.desc_event* sc_find_event( const char* name )
179912027Sjungma@eit.uni-kl.de{
180012027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->get_object_manager()->find_event( name );
180112027Sjungma@eit.uni-kl.de}
180212027Sjungma@eit.uni-kl.de
180312027Sjungma@eit.uni-kl.desc_object* sc_find_object( const char* name )
180412027Sjungma@eit.uni-kl.de{
180512027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->get_object_manager()->find_object( name );
180612027Sjungma@eit.uni-kl.de}
180712027Sjungma@eit.uni-kl.de
180812027Sjungma@eit.uni-kl.de
180912027Sjungma@eit.uni-kl.deconst sc_time&
181012027Sjungma@eit.uni-kl.desc_max_time()
181112027Sjungma@eit.uni-kl.de{
181212027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->max_time();
181312027Sjungma@eit.uni-kl.de}
181412027Sjungma@eit.uni-kl.de
181512027Sjungma@eit.uni-kl.deconst sc_time&
181612027Sjungma@eit.uni-kl.desc_time_stamp()
181712027Sjungma@eit.uni-kl.de{
181812027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->time_stamp();
181912027Sjungma@eit.uni-kl.de}
182012027Sjungma@eit.uni-kl.de
182112027Sjungma@eit.uni-kl.dedouble
182212027Sjungma@eit.uni-kl.desc_simulation_time()
182312027Sjungma@eit.uni-kl.de{
182412027Sjungma@eit.uni-kl.de    static bool warn_simulation_time=true;
182512027Sjungma@eit.uni-kl.de    if ( warn_simulation_time )
182612027Sjungma@eit.uni-kl.de    {
182712027Sjungma@eit.uni-kl.de        warn_simulation_time=false;
182812027Sjungma@eit.uni-kl.de        SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
182912027Sjungma@eit.uni-kl.de	    "sc_simulation_time() is deprecated use sc_time_stamp()" );
183012027Sjungma@eit.uni-kl.de    }
183112027Sjungma@eit.uni-kl.de    return sc_get_curr_simcontext()->time_stamp().to_default_time_units();
183212027Sjungma@eit.uni-kl.de}
183312027Sjungma@eit.uni-kl.de
183412027Sjungma@eit.uni-kl.devoid
183512027Sjungma@eit.uni-kl.desc_defunct_process_function( sc_module* )
183612027Sjungma@eit.uni-kl.de{
183712027Sjungma@eit.uni-kl.de    // This function is pointed to by defunct sc_thread_process'es and
183812027Sjungma@eit.uni-kl.de    // sc_cthread_process'es. In a correctly constructed world, this
183912027Sjungma@eit.uni-kl.de    // function should never be called; hence the assert.
184012027Sjungma@eit.uni-kl.de    assert( false );
184112027Sjungma@eit.uni-kl.de}
184212027Sjungma@eit.uni-kl.de
184312027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
184412027Sjungma@eit.uni-kl.de//"sc_set_stop_mode"
184512027Sjungma@eit.uni-kl.de//
184612027Sjungma@eit.uni-kl.de// This function sets the mode of operation when sc_stop() is called.
184712027Sjungma@eit.uni-kl.de//     mode = SC_STOP_IMMEDIATE or SC_STOP_FINISH_DELTA.
184812027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
184912027Sjungma@eit.uni-kl.devoid sc_set_stop_mode(sc_stop_mode mode)
185012027Sjungma@eit.uni-kl.de{
185112027Sjungma@eit.uni-kl.de    if ( sc_is_running() )
185212027Sjungma@eit.uni-kl.de    {
185312027Sjungma@eit.uni-kl.de        SC_REPORT_ERROR(SC_ID_STOP_MODE_AFTER_START_,"");
185412027Sjungma@eit.uni-kl.de    }
185512027Sjungma@eit.uni-kl.de    else
185612027Sjungma@eit.uni-kl.de    {
185712027Sjungma@eit.uni-kl.de        switch( mode )
185812027Sjungma@eit.uni-kl.de        {
185912027Sjungma@eit.uni-kl.de          case SC_STOP_IMMEDIATE:
186012027Sjungma@eit.uni-kl.de          case SC_STOP_FINISH_DELTA:
186112027Sjungma@eit.uni-kl.de              stop_mode = mode;
186212027Sjungma@eit.uni-kl.de              break;
186312027Sjungma@eit.uni-kl.de          default:
186412027Sjungma@eit.uni-kl.de              break;
186512027Sjungma@eit.uni-kl.de        }
186612027Sjungma@eit.uni-kl.de    }
186712027Sjungma@eit.uni-kl.de}
186812027Sjungma@eit.uni-kl.de
186912027Sjungma@eit.uni-kl.desc_stop_mode
187012027Sjungma@eit.uni-kl.desc_get_stop_mode()
187112027Sjungma@eit.uni-kl.de{
187212027Sjungma@eit.uni-kl.de    return stop_mode;
187312027Sjungma@eit.uni-kl.de}
187412027Sjungma@eit.uni-kl.de
187512027Sjungma@eit.uni-kl.debool sc_is_unwinding()
187612027Sjungma@eit.uni-kl.de{
187712027Sjungma@eit.uni-kl.de    return sc_get_current_process_handle().is_unwinding();
187812027Sjungma@eit.uni-kl.de}
187912027Sjungma@eit.uni-kl.de
188012027Sjungma@eit.uni-kl.de// The IEEE 1666 Standard for 2011 designates that the treatment of
188112027Sjungma@eit.uni-kl.de// certain process control interactions as being "implementation dependent".
188212027Sjungma@eit.uni-kl.de// These interactions are:
188312027Sjungma@eit.uni-kl.de//   (1) What happens when a resume() call is performed on a disabled,
188412027Sjungma@eit.uni-kl.de//       suspended process.
188512027Sjungma@eit.uni-kl.de//   (2) What happens when sync_reset_on() or sync_reset_off() is called
188612027Sjungma@eit.uni-kl.de//       on a suspended process.
188712027Sjungma@eit.uni-kl.de//   (3) What happens when the value specified in a reset_signal_is()
188812027Sjungma@eit.uni-kl.de//       call changes value while a process is suspended.
188912027Sjungma@eit.uni-kl.de//
189012027Sjungma@eit.uni-kl.de// By default this Proof of Concept implementation reports an error
189112027Sjungma@eit.uni-kl.de// for these interactions. However, the implementation also provides
189212027Sjungma@eit.uni-kl.de// a non-error treatment. The non-error treatment for the interactions is:
189312027Sjungma@eit.uni-kl.de//   (1) A resume() call performed on a disabled, suspended process will
189412027Sjungma@eit.uni-kl.de//       mark the process as no longer suspended, and if it is capable
189512027Sjungma@eit.uni-kl.de//       of execution (not waiting on any events) it will be placed on
189612027Sjungma@eit.uni-kl.de//       the queue of runnable processes. See the state diagram below.
189712027Sjungma@eit.uni-kl.de//   (2) A call to sync_reset_on() or sync_reset_off() will set or clear
189812027Sjungma@eit.uni-kl.de//       the synchronous reset flag. Whether the process is in reset or
189912027Sjungma@eit.uni-kl.de//       not will be determined when the process actually executes by
190012027Sjungma@eit.uni-kl.de//       looking at the flag's value at that time.
190112027Sjungma@eit.uni-kl.de//   (3) If a suspended process has a reset_signal_is() specification
190212027Sjungma@eit.uni-kl.de//       the value of the reset variable at the time of its next execution
190312027Sjungma@eit.uni-kl.de//       will determine whether it is in reset or not.
190412027Sjungma@eit.uni-kl.de//
190512027Sjungma@eit.uni-kl.de// TO GET THE NON-ERROR BEHAVIOR SET THE VARIABLE BELOW TO TRUE.
190612027Sjungma@eit.uni-kl.de//
190712027Sjungma@eit.uni-kl.de// This can be done in this source before you build the library, or you
190812027Sjungma@eit.uni-kl.de// can use an assignment as the first statement in your sc_main() function:
190912027Sjungma@eit.uni-kl.de//    sc_core::sc_allow_process_control_corners = true;
191012027Sjungma@eit.uni-kl.de
191112027Sjungma@eit.uni-kl.debool sc_allow_process_control_corners = false;
191212027Sjungma@eit.uni-kl.de
191312027Sjungma@eit.uni-kl.de// The state transition diagram for the interaction of disable and suspend
191412027Sjungma@eit.uni-kl.de// when sc_allow_process_control_corners is true is shown below:
191512027Sjungma@eit.uni-kl.de//
191612027Sjungma@eit.uni-kl.de// ......................................................................
191712027Sjungma@eit.uni-kl.de// .         ENABLED                    .           DISABLED            .
191812027Sjungma@eit.uni-kl.de// .                                    .                               .
191912027Sjungma@eit.uni-kl.de// .                 +----------+    disable      +----------+          .
192012027Sjungma@eit.uni-kl.de// .   +------------>|          |-------.-------->|          |          .
192112027Sjungma@eit.uni-kl.de// .   |             | runnable |       .         | runnable |          .
192212027Sjungma@eit.uni-kl.de// .   |     +-------|          |<------.---------|          |------+   .
192312027Sjungma@eit.uni-kl.de// .   |     |       +----------+     enable      +----------+      |   .
192412027Sjungma@eit.uni-kl.de// .   |     |          |    ^          .            |    ^         |   .
192512027Sjungma@eit.uni-kl.de// .   |     |  suspend |    | resume   .    suspend |    | resume  |   .
192612027Sjungma@eit.uni-kl.de// .   |     |          V    |          .            V    |         |   .
192712027Sjungma@eit.uni-kl.de// .   |     |       +----------+    disable      +----------+      |   .
192812027Sjungma@eit.uni-kl.de// .   |     |       | suspend  |-------.-------->| suspend  |      |   .
192912027Sjungma@eit.uni-kl.de// . t |   r |       |          |       .         |          |      | r .
193012027Sjungma@eit.uni-kl.de// . r |   u |       |  ready   |<------.---------|  ready   |      | u .
193112027Sjungma@eit.uni-kl.de// . i |   n |       +----------+     enable      +----------+      | n .
193212027Sjungma@eit.uni-kl.de// . g |   / |         ^                .                           | / .
193312027Sjungma@eit.uni-kl.de// . g |   w |  trigger|                .                           | w .
193412027Sjungma@eit.uni-kl.de// . e |   a |         |                .                           | a .
193512027Sjungma@eit.uni-kl.de// . r |   i |       +----------+    disable      +----------+      | i .
193612027Sjungma@eit.uni-kl.de// .   |   t |       | suspend  |-------.-------->| suspend  |      | t .
193712027Sjungma@eit.uni-kl.de// .   |     |       |          |       .         |          |      |   .
193812027Sjungma@eit.uni-kl.de// .   |     |       | waiting  |<------.---------| waiting  |      |   .
193912027Sjungma@eit.uni-kl.de// .   |     |       +----------+     enable      +----------+      |   .
194012027Sjungma@eit.uni-kl.de// .   |     |          |    ^          .            |    ^         |   .
194112027Sjungma@eit.uni-kl.de// .   |     |  suspend |    | resume   .    suspend |    | resume  |   .
194212027Sjungma@eit.uni-kl.de// .   |     |          V    |          .            V    |         |   .
194312027Sjungma@eit.uni-kl.de// .   |     |       +----------+    disable      +----------+      |   .
194412027Sjungma@eit.uni-kl.de// .   |     +------>|          |-------.-------->|          |      |   .
194512027Sjungma@eit.uni-kl.de// .   |             | waiting  |       .         | waiting  |      |   .
194612027Sjungma@eit.uni-kl.de// .   +-------------|          |<------.---------|          |<-----+   .
194712027Sjungma@eit.uni-kl.de// .                 +----------+     enable      +----------+          .
194812027Sjungma@eit.uni-kl.de// .                                    .                               .
194912027Sjungma@eit.uni-kl.de// ......................................................................
195012027Sjungma@eit.uni-kl.de
195112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
195212027Sjungma@eit.uni-kl.de
195312027Sjungma@eit.uni-kl.destatic std::ostream&
195412027Sjungma@eit.uni-kl.deprint_status_expression( std::ostream& os, sc_status s );
195512027Sjungma@eit.uni-kl.de
195612027Sjungma@eit.uni-kl.de// utility helper to print a simulation status
195712027Sjungma@eit.uni-kl.destd::ostream& operator << ( std::ostream& os, sc_status s )
195812027Sjungma@eit.uni-kl.de{
195912027Sjungma@eit.uni-kl.de    // print primitive values
196012027Sjungma@eit.uni-kl.de    switch(s)
196112027Sjungma@eit.uni-kl.de    {
196212027Sjungma@eit.uni-kl.de#   define PRINT_STATUS( Status ) \
196312027Sjungma@eit.uni-kl.de      case Status: { os << #Status; } break
196412027Sjungma@eit.uni-kl.de
196512027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_UNITIALIZED );
196612027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_ELABORATION );
196712027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_BEFORE_END_OF_ELABORATION );
196812027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_END_OF_ELABORATION );
196912027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_START_OF_SIMULATION );
197012027Sjungma@eit.uni-kl.de
197112027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_RUNNING );
197212027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_PAUSED );
197312027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_STOPPED );
197412027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_END_OF_SIMULATION );
197512027Sjungma@eit.uni-kl.de
197612027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_END_OF_INITIALIZATION );
197712027Sjungma@eit.uni-kl.de//      PRINT_STATUS( SC_END_OF_EVALUATION );
197812027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_END_OF_UPDATE );
197912027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_BEFORE_TIMESTEP );
198012027Sjungma@eit.uni-kl.de
198112027Sjungma@eit.uni-kl.de      PRINT_STATUS( SC_STATUS_ANY );
198212027Sjungma@eit.uni-kl.de
198312027Sjungma@eit.uni-kl.de#   undef PRINT_STATUS
198412027Sjungma@eit.uni-kl.de    default:
198512027Sjungma@eit.uni-kl.de
198612027Sjungma@eit.uni-kl.de      if( s & SC_STATUS_ANY ) // combination of status bits
198712027Sjungma@eit.uni-kl.de        print_status_expression( os, s );
198812027Sjungma@eit.uni-kl.de      else                    // invalid number, print hex value
198912027Sjungma@eit.uni-kl.de        os << "0x" << std::hex << +s;
199012027Sjungma@eit.uni-kl.de    }
199112027Sjungma@eit.uni-kl.de
199212027Sjungma@eit.uni-kl.de    return os;
199312027Sjungma@eit.uni-kl.de}
199412027Sjungma@eit.uni-kl.de
199512027Sjungma@eit.uni-kl.de// pretty-print a combination of sc_status bits (i.e. a callback mask)
199612027Sjungma@eit.uni-kl.destatic std::ostream&
199712027Sjungma@eit.uni-kl.deprint_status_expression( std::ostream& os, sc_status s )
199812027Sjungma@eit.uni-kl.de{
199912027Sjungma@eit.uni-kl.de    std::vector<sc_status> bits;
200012027Sjungma@eit.uni-kl.de    unsigned               is_set = SC_ELABORATION;
200112027Sjungma@eit.uni-kl.de
200212027Sjungma@eit.uni-kl.de    // collect bits
200312027Sjungma@eit.uni-kl.de    while( is_set <= SC_STATUS_LAST )
200412027Sjungma@eit.uni-kl.de    {
200512027Sjungma@eit.uni-kl.de        if( s & is_set )
200612027Sjungma@eit.uni-kl.de            bits.push_back( (sc_status)is_set );
200712027Sjungma@eit.uni-kl.de        is_set <<= 1;
200812027Sjungma@eit.uni-kl.de    }
200912027Sjungma@eit.uni-kl.de    if( s & ~SC_STATUS_ANY ) // remaining bits
201012027Sjungma@eit.uni-kl.de        bits.push_back( (sc_status)( s & ~SC_STATUS_ANY ) );
201112027Sjungma@eit.uni-kl.de
201212027Sjungma@eit.uni-kl.de    // print expression
201312027Sjungma@eit.uni-kl.de    std::vector<sc_status>::size_type i=0, n=bits.size();
201412027Sjungma@eit.uni-kl.de    if ( n>1 )
201512027Sjungma@eit.uni-kl.de        os << "(";
201612027Sjungma@eit.uni-kl.de    for( ; i<n-1; ++i )
201712027Sjungma@eit.uni-kl.de        os << bits[i] << "|";
201812027Sjungma@eit.uni-kl.de    os << bits[i];
201912027Sjungma@eit.uni-kl.de    if ( n>1 )
202012027Sjungma@eit.uni-kl.de        os << ")";
202112027Sjungma@eit.uni-kl.de    return os;
202212027Sjungma@eit.uni-kl.de}
202312027Sjungma@eit.uni-kl.de
202412027Sjungma@eit.uni-kl.de} // namespace sc_core
202512027Sjungma@eit.uni-kl.de
202612027Sjungma@eit.uni-kl.de/*****************************************************************************
202712027Sjungma@eit.uni-kl.de
202812027Sjungma@eit.uni-kl.de  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
202912027Sjungma@eit.uni-kl.de  changes you are making here.
203012027Sjungma@eit.uni-kl.de
203112027Sjungma@eit.uni-kl.de      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
203212027Sjungma@eit.uni-kl.de  Description of Modification: - Added sc_stop() detection into initial_crunch
203312027Sjungma@eit.uni-kl.de                                 and crunch. This makes it possible to exit out
203412027Sjungma@eit.uni-kl.de                                 of a combinational loop using sc_stop().
203512027Sjungma@eit.uni-kl.de
203612027Sjungma@eit.uni-kl.de      Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
203712027Sjungma@eit.uni-kl.de  Description of Modification: - sc_stop mode
203812027Sjungma@eit.uni-kl.de                               - phase callbacks
203912027Sjungma@eit.uni-kl.de
204012027Sjungma@eit.uni-kl.de      Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
204112027Sjungma@eit.uni-kl.de                               25 August 2003
204212027Sjungma@eit.uni-kl.de  Description of Modification: - support for dynamic process
204312027Sjungma@eit.uni-kl.de                               - support for sc export registry
204412027Sjungma@eit.uni-kl.de                               - new member methods elaborate(),
204512027Sjungma@eit.uni-kl.de				 prepare_to_simulate(), and initial_crunch()
204612027Sjungma@eit.uni-kl.de				 that are invoked by initialize() in that order
204712027Sjungma@eit.uni-kl.de                               - implement sc_get_last_created_process_handle() for use
204812027Sjungma@eit.uni-kl.de                                 before simulation starts
204912027Sjungma@eit.uni-kl.de                               - remove "set_curr_proc(handle)" from
205012027Sjungma@eit.uni-kl.de                                 register_method_process and
205112027Sjungma@eit.uni-kl.de                                 register_thread_process - led to bugs
205212027Sjungma@eit.uni-kl.de
205312027Sjungma@eit.uni-kl.de      Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 04 Sep 2003
205412027Sjungma@eit.uni-kl.de  Description of Modification: - changed process existence structures to
205512027Sjungma@eit.uni-kl.de				 linked lists to eliminate exponential
205612027Sjungma@eit.uni-kl.de				 execution problem with using sc_pvector.
205712027Sjungma@eit.uni-kl.de *****************************************************************************/
205812027Sjungma@eit.uni-kl.de// $Log: sc_simcontext.cpp,v $
205912027Sjungma@eit.uni-kl.de// Revision 1.37  2011/08/29 18:04:32  acg
206012027Sjungma@eit.uni-kl.de//  Philipp A. Hartmann: miscellaneous clean ups.
206112027Sjungma@eit.uni-kl.de//
206212027Sjungma@eit.uni-kl.de// Revision 1.36  2011/08/26 20:46:10  acg
206312027Sjungma@eit.uni-kl.de//  Andy Goodrich: moved the modification log to the end of the file to
206412027Sjungma@eit.uni-kl.de//  eliminate source line number skew when check-ins are done.
206512027Sjungma@eit.uni-kl.de//
206612027Sjungma@eit.uni-kl.de// Revision 1.35  2011/08/24 22:05:51  acg
206712027Sjungma@eit.uni-kl.de//  Torsten Maehne: initialization changes to remove warnings.
206812027Sjungma@eit.uni-kl.de//
206912027Sjungma@eit.uni-kl.de// Revision 1.34  2011/08/04 17:15:28  acg
207012027Sjungma@eit.uni-kl.de//  Andy Goodrich: added documentation to crunch() routine.
207112027Sjungma@eit.uni-kl.de//
207212027Sjungma@eit.uni-kl.de// Revision 1.32  2011/07/24 11:16:36  acg
207312027Sjungma@eit.uni-kl.de//  Philipp A. Hartmann: fix reference counting on deferred deletions of
207412027Sjungma@eit.uni-kl.de//  processes.
207512027Sjungma@eit.uni-kl.de//
207612027Sjungma@eit.uni-kl.de// Revision 1.31  2011/07/01 18:49:07  acg
207712027Sjungma@eit.uni-kl.de//  Andy Goodrich: moved pln() from sc_simcontext.cpp to sc_ver.cpp.
207812027Sjungma@eit.uni-kl.de//
207912027Sjungma@eit.uni-kl.de// Revision 1.30  2011/05/09 04:07:49  acg
208012027Sjungma@eit.uni-kl.de//  Philipp A. Hartmann:
208112027Sjungma@eit.uni-kl.de//    (1) Restore hierarchy in all phase callbacks.
208212027Sjungma@eit.uni-kl.de//    (2) Ensure calls to before_end_of_elaboration.
208312027Sjungma@eit.uni-kl.de//
208412027Sjungma@eit.uni-kl.de// Revision 1.29  2011/04/08 22:39:09  acg
208512027Sjungma@eit.uni-kl.de//  Andy Goodrich: moved method invocation code to sc_method.h so that the
208612027Sjungma@eit.uni-kl.de//  details are hidden from sc_simcontext.
208712027Sjungma@eit.uni-kl.de//
208812027Sjungma@eit.uni-kl.de// Revision 1.28  2011/04/05 20:50:57  acg
208912027Sjungma@eit.uni-kl.de//  Andy Goodrich:
209012027Sjungma@eit.uni-kl.de//    (1) changes to make sure that event(), posedge() and negedge() only
209112027Sjungma@eit.uni-kl.de//        return true if the clock has not moved.
209212027Sjungma@eit.uni-kl.de//    (2) fixes for method self-resumes.
209312027Sjungma@eit.uni-kl.de//    (3) added SC_PRERELEASE_VERSION
209412027Sjungma@eit.uni-kl.de//    (4) removed kernel events from the object hierarchy, added
209512027Sjungma@eit.uni-kl.de//        sc_hierarchy_name_exists().
209612027Sjungma@eit.uni-kl.de//
209712027Sjungma@eit.uni-kl.de// Revision 1.27  2011/04/05 06:14:15  acg
209812027Sjungma@eit.uni-kl.de//  Andy Goodrich: fix typo.
209912027Sjungma@eit.uni-kl.de//
210012027Sjungma@eit.uni-kl.de// Revision 1.26  2011/04/05 06:03:32  acg
210112027Sjungma@eit.uni-kl.de//  Philipp A. Hartmann: added code to set ready to run bit for a suspended
210212027Sjungma@eit.uni-kl.de//  process that does not have dont_initialize specified at simulation
210312027Sjungma@eit.uni-kl.de//  start up.
210412027Sjungma@eit.uni-kl.de//
210512027Sjungma@eit.uni-kl.de// Revision 1.25  2011/04/01 21:31:55  acg
210612027Sjungma@eit.uni-kl.de//  Andy Goodrich: make sure processes suspended before the start of execution
210712027Sjungma@eit.uni-kl.de//  don't get scheduled for initial execution.
210812027Sjungma@eit.uni-kl.de//
210912027Sjungma@eit.uni-kl.de// Revision 1.24  2011/03/28 13:02:52  acg
211012027Sjungma@eit.uni-kl.de//  Andy Goodrich: Changes for disable() interactions.
211112027Sjungma@eit.uni-kl.de//
211212027Sjungma@eit.uni-kl.de// Revision 1.23  2011/03/12 21:07:51  acg
211312027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes to kernel generated event support.
211412027Sjungma@eit.uni-kl.de//
211512027Sjungma@eit.uni-kl.de// Revision 1.22  2011/03/07 17:38:43  acg
211612027Sjungma@eit.uni-kl.de//  Andy Goodrich: tightening up of checks for undefined interaction between
211712027Sjungma@eit.uni-kl.de//  synchronous reset and suspend.
211812027Sjungma@eit.uni-kl.de//
211912027Sjungma@eit.uni-kl.de// Revision 1.21  2011/03/06 19:57:11  acg
212012027Sjungma@eit.uni-kl.de//  Andy Goodrich: refinements for the illegal suspend - synchronous reset
212112027Sjungma@eit.uni-kl.de//  interaction.
212212027Sjungma@eit.uni-kl.de//
212312027Sjungma@eit.uni-kl.de// Revision 1.20  2011/03/06 15:58:50  acg
212412027Sjungma@eit.uni-kl.de//  Andy Goodrich: added escape to turn off process control corner case
212512027Sjungma@eit.uni-kl.de//  checks.
212612027Sjungma@eit.uni-kl.de//
212712027Sjungma@eit.uni-kl.de// Revision 1.19  2011/03/05 04:45:16  acg
212812027Sjungma@eit.uni-kl.de//  Andy Goodrich: moved active process calculation to the sc_simcontext class.
212912027Sjungma@eit.uni-kl.de//
213012027Sjungma@eit.uni-kl.de// Revision 1.18  2011/03/05 01:39:21  acg
213112027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes for named events.
213212027Sjungma@eit.uni-kl.de//
213312027Sjungma@eit.uni-kl.de// Revision 1.17  2011/02/18 20:27:14  acg
213412027Sjungma@eit.uni-kl.de//  Andy Goodrich: Updated Copyrights.
213512027Sjungma@eit.uni-kl.de//
213612027Sjungma@eit.uni-kl.de// Revision 1.16  2011/02/17 19:53:28  acg
213712027Sjungma@eit.uni-kl.de//  Andy Goodrich: eliminated use of ready_to_run() as part of process control
213812027Sjungma@eit.uni-kl.de//  simplification.
213912027Sjungma@eit.uni-kl.de//
214012027Sjungma@eit.uni-kl.de// Revision 1.15  2011/02/13 21:47:38  acg
214112027Sjungma@eit.uni-kl.de//  Andy Goodrich: update copyright notice.
214212027Sjungma@eit.uni-kl.de//
214312027Sjungma@eit.uni-kl.de// Revision 1.14  2011/02/11 13:25:24  acg
214412027Sjungma@eit.uni-kl.de//  Andy Goodrich: Philipp A. Hartmann's changes:
214512027Sjungma@eit.uni-kl.de//    (1) Removal of SC_CTHREAD method overloads.
214612027Sjungma@eit.uni-kl.de//    (2) New exception processing code.
214712027Sjungma@eit.uni-kl.de//
214812027Sjungma@eit.uni-kl.de// Revision 1.13  2011/02/08 08:42:50  acg
214912027Sjungma@eit.uni-kl.de//  Andy Goodrich: fix ordering of check for stopped versus paused.
215012027Sjungma@eit.uni-kl.de//
215112027Sjungma@eit.uni-kl.de// Revision 1.12  2011/02/07 19:17:20  acg
215212027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes for IEEE 1666 compatibility.
215312027Sjungma@eit.uni-kl.de//
215412027Sjungma@eit.uni-kl.de// Revision 1.11  2011/02/02 07:18:11  acg
215512027Sjungma@eit.uni-kl.de//  Andy Goodrich: removed toggle() calls for the new crunch() toggle usage.
215612027Sjungma@eit.uni-kl.de//
215712027Sjungma@eit.uni-kl.de// Revision 1.10  2011/02/01 23:01:53  acg
215812027Sjungma@eit.uni-kl.de//  Andy Goodrich: removed dead code.
215912027Sjungma@eit.uni-kl.de//
216012027Sjungma@eit.uni-kl.de// Revision 1.9  2011/02/01 21:11:59  acg
216112027Sjungma@eit.uni-kl.de//  Andy Goodrich:
216212027Sjungma@eit.uni-kl.de//  (1) Use of new toggle_methods() and toggle_threads() run queue methods
216312027Sjungma@eit.uni-kl.de//      to make sure the thread run queue does not execute when allow preempt_me()
216412027Sjungma@eit.uni-kl.de//      is called from an SC_METHOD.
216512027Sjungma@eit.uni-kl.de//  (2) Use of execute_thread_next() to allow thread execution in the current
216612027Sjungma@eit.uni-kl.de//      delta cycle() rather than push_runnable_thread_front which executed
216712027Sjungma@eit.uni-kl.de//      in the following cycle.
216812027Sjungma@eit.uni-kl.de//
216912027Sjungma@eit.uni-kl.de// Revision 1.8  2011/01/25 20:50:37  acg
217012027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes for IEEE 1666 2011.
217112027Sjungma@eit.uni-kl.de//
217212027Sjungma@eit.uni-kl.de// Revision 1.7  2011/01/19 23:21:50  acg
217312027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes for IEEE 1666 2011
217412027Sjungma@eit.uni-kl.de//
217512027Sjungma@eit.uni-kl.de// Revision 1.6  2011/01/18 20:10:45  acg
217612027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes for IEEE1666_2011 semantics.
217712027Sjungma@eit.uni-kl.de//
217812027Sjungma@eit.uni-kl.de// Revision 1.5  2010/11/20 17:10:57  acg
217912027Sjungma@eit.uni-kl.de//  Andy Goodrich: reset processing changes for new IEEE 1666 standard.
218012027Sjungma@eit.uni-kl.de//
218112027Sjungma@eit.uni-kl.de// Revision 1.4  2010/07/22 20:02:33  acg
218212027Sjungma@eit.uni-kl.de//  Andy Goodrich: bug fixes.
218312027Sjungma@eit.uni-kl.de//
218412027Sjungma@eit.uni-kl.de// Revision 1.3  2008/05/22 17:06:26  acg
218512027Sjungma@eit.uni-kl.de//  Andy Goodrich: updated copyright notice to include 2008.
218612027Sjungma@eit.uni-kl.de//
218712027Sjungma@eit.uni-kl.de// Revision 1.2  2007/09/20 20:32:35  acg
218812027Sjungma@eit.uni-kl.de//  Andy Goodrich: changes to the semantics of throw_it() to match the
218912027Sjungma@eit.uni-kl.de//  specification. A call to throw_it() will immediately suspend the calling
219012027Sjungma@eit.uni-kl.de//  thread until all the throwees have executed. At that point the calling
219112027Sjungma@eit.uni-kl.de//  thread will be restarted before the execution of any other threads.
219212027Sjungma@eit.uni-kl.de//
219312027Sjungma@eit.uni-kl.de// Revision 1.1.1.1  2006/12/15 20:20:05  acg
219412027Sjungma@eit.uni-kl.de// SystemC 2.3
219512027Sjungma@eit.uni-kl.de//
219612027Sjungma@eit.uni-kl.de// Revision 1.21  2006/08/29 23:37:13  acg
219712027Sjungma@eit.uni-kl.de//  Andy Goodrich: Added check for negative time.
219812027Sjungma@eit.uni-kl.de//
219912027Sjungma@eit.uni-kl.de// Revision 1.20  2006/05/26 20:33:16  acg
220012027Sjungma@eit.uni-kl.de//   Andy Goodrich: changes required by additional platform compilers (i.e.,
220112027Sjungma@eit.uni-kl.de//   Microsoft VC++, Sun Forte, HP aCC).
220212027Sjungma@eit.uni-kl.de//
220312027Sjungma@eit.uni-kl.de// Revision 1.19  2006/05/08 17:59:52  acg
220412027Sjungma@eit.uni-kl.de//  Andy Goodrich: added a check before m_curr_time is set to make sure it
220512027Sjungma@eit.uni-kl.de//  is not set to a time before its current value. This will treat
220612027Sjungma@eit.uni-kl.de//  sc_event.notify( ) calls with negative times as calls with a zero time.
220712027Sjungma@eit.uni-kl.de//
220812027Sjungma@eit.uni-kl.de// Revision 1.18  2006/04/20 17:08:17  acg
220912027Sjungma@eit.uni-kl.de//  Andy Goodrich: 3.0 style process changes.
221012027Sjungma@eit.uni-kl.de//
221112027Sjungma@eit.uni-kl.de// Revision 1.17  2006/04/11 23:13:21  acg
221212027Sjungma@eit.uni-kl.de//   Andy Goodrich: Changes for reduced reset support that only includes
221312027Sjungma@eit.uni-kl.de//   sc_cthread, but has preliminary hooks for expanding to method and thread
221412027Sjungma@eit.uni-kl.de//   processes also.
221512027Sjungma@eit.uni-kl.de//
221612027Sjungma@eit.uni-kl.de// Revision 1.16  2006/03/21 00:00:34  acg
221712027Sjungma@eit.uni-kl.de//   Andy Goodrich: changed name of sc_get_current_process_base() to be
221812027Sjungma@eit.uni-kl.de//   sc_get_current_process_b() since its returning an sc_process_b instance.
221912027Sjungma@eit.uni-kl.de//
222012027Sjungma@eit.uni-kl.de// Revision 1.15  2006/03/13 20:26:50  acg
222112027Sjungma@eit.uni-kl.de//  Andy Goodrich: Addition of forward class declarations, e.g.,
222212027Sjungma@eit.uni-kl.de//  sc_reset, to keep gcc 4.x happy.
222312027Sjungma@eit.uni-kl.de//
222412027Sjungma@eit.uni-kl.de// Revision 1.14  2006/02/02 23:42:41  acg
222512027Sjungma@eit.uni-kl.de//  Andy Goodrich: implemented a much better fix to the sc_event_finder
222612027Sjungma@eit.uni-kl.de//  proliferation problem. This new version allocates only a single event
222712027Sjungma@eit.uni-kl.de//  finder for each port for each type of event, e.g., pos(), neg(), and
222812027Sjungma@eit.uni-kl.de//  value_change(). The event finder persists as long as the port does,
222912027Sjungma@eit.uni-kl.de//  which is what the LRM dictates. Because only a single instance is
223012027Sjungma@eit.uni-kl.de//  allocated for each event type per port there is not a potential
223112027Sjungma@eit.uni-kl.de//  explosion of storage as was true in the 2.0.1/2.1 versions.
223212027Sjungma@eit.uni-kl.de//
223312027Sjungma@eit.uni-kl.de// Revision 1.13  2006/02/02 21:29:10  acg
223412027Sjungma@eit.uni-kl.de//  Andy Goodrich: removed the call to sc_event_finder::free_instances() that
223512027Sjungma@eit.uni-kl.de//  was in end_of_elaboration(), leaving only the call in clean(). This is
223612027Sjungma@eit.uni-kl.de//  because the LRM states that sc_event_finder instances are persistent as
223712027Sjungma@eit.uni-kl.de//  long as the sc_module hierarchy is valid.
223812027Sjungma@eit.uni-kl.de//
223912027Sjungma@eit.uni-kl.de// Revision 1.12  2006/02/02 21:09:50  acg
224012027Sjungma@eit.uni-kl.de//  Andy Goodrich: added call to sc_event_finder::free_instances in the clean()
224112027Sjungma@eit.uni-kl.de//  method.
224212027Sjungma@eit.uni-kl.de//
224312027Sjungma@eit.uni-kl.de// Revision 1.11  2006/02/02 20:43:14  acg
224412027Sjungma@eit.uni-kl.de//  Andy Goodrich: Added an existence linked list to sc_event_finder so that
224512027Sjungma@eit.uni-kl.de//  the dynamically allocated instances can be freed after port binding
224612027Sjungma@eit.uni-kl.de//  completes. This replaces the individual deletions in ~sc_bind_ef, as these
224712027Sjungma@eit.uni-kl.de//  caused an exception if an sc_event_finder instance was used more than
224812027Sjungma@eit.uni-kl.de//  once, due to a double freeing of the instance.
224912027Sjungma@eit.uni-kl.de//
225012027Sjungma@eit.uni-kl.de// Revision 1.10  2006/01/31 21:43:26  acg
225112027Sjungma@eit.uni-kl.de//  Andy Goodrich: added comments in constructor to highlight environmental
225212027Sjungma@eit.uni-kl.de//  overrides section.
225312027Sjungma@eit.uni-kl.de//
225412027Sjungma@eit.uni-kl.de// Revision 1.9  2006/01/26 21:04:54  acg
225512027Sjungma@eit.uni-kl.de//  Andy Goodrich: deprecation message changes and additional messages.
225612027Sjungma@eit.uni-kl.de//
225712027Sjungma@eit.uni-kl.de// Revision 1.8  2006/01/25 00:31:19  acg
225812027Sjungma@eit.uni-kl.de//  Andy Goodrich: Changed over to use a standard message id of
225912027Sjungma@eit.uni-kl.de//  SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
226012027Sjungma@eit.uni-kl.de//
226112027Sjungma@eit.uni-kl.de// Revision 1.7  2006/01/24 20:49:05  acg
226212027Sjungma@eit.uni-kl.de// Andy Goodrich: changes to remove the use of deprecated features within the
226312027Sjungma@eit.uni-kl.de// simulator, and to issue warning messages when deprecated features are used.
226412027Sjungma@eit.uni-kl.de//
226512027Sjungma@eit.uni-kl.de// Revision 1.6  2006/01/19 00:29:52  acg
226612027Sjungma@eit.uni-kl.de// Andy Goodrich: Yet another implementation for signal write checking. This
226712027Sjungma@eit.uni-kl.de// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
226812027Sjungma@eit.uni-kl.de// DISABLE will disable write checking on signals.
226912027Sjungma@eit.uni-kl.de//
227012027Sjungma@eit.uni-kl.de// Revision 1.5  2006/01/13 18:44:30  acg
227112027Sjungma@eit.uni-kl.de// Added $Log to record CVS changes into the source.
227212027Sjungma@eit.uni-kl.de//
227312027Sjungma@eit.uni-kl.de// Revision 1.4  2006/01/03 23:18:44  acg
227412027Sjungma@eit.uni-kl.de// Changed copyright to include 2006.
227512027Sjungma@eit.uni-kl.de//
227612027Sjungma@eit.uni-kl.de// Revision 1.3  2005/12/20 22:11:10  acg
227712027Sjungma@eit.uni-kl.de// Fixed $Log lines.
227812027Sjungma@eit.uni-kl.de//
227912027Sjungma@eit.uni-kl.de// Revision 1.2  2005/12/20 22:02:30  acg
228012027Sjungma@eit.uni-kl.de// Changed where delta cycles are incremented to match IEEE 1666. Added the
228112027Sjungma@eit.uni-kl.de// event_occurred() method to hide how delta cycle comparisions are done within
228212027Sjungma@eit.uni-kl.de// sc_simcontext. Changed the boolean update_phase to an enum that shows all
228312027Sjungma@eit.uni-kl.de// the phases.
228412027Sjungma@eit.uni-kl.de// Taf!
2285